wd33c93.c
上传用户:lgb322
上传日期:2013-02-24
资源大小:30529k
文件大小:65k
源码类别:

嵌入式Linux

开发平台:

Unix_Linux

  1. /*
  2.  *    wd33c93.c - Linux-68k device driver for the Commodore
  3.  *                Amiga A2091/590 SCSI controller card
  4.  *
  5.  * Copyright (c) 1996 John Shifflett, GeoLog Consulting
  6.  *    john@geolog.com
  7.  *    jshiffle@netcom.com
  8.  *
  9.  * This program is free software; you can redistribute it and/or modify
  10.  * it under the terms of the GNU General Public License as published by
  11.  * the Free Software Foundation; either version 2, or (at your option)
  12.  * any later version.
  13.  *
  14.  * This program is distributed in the hope that it will be useful,
  15.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  17.  * GNU General Public License for more details.
  18.  *
  19.  *
  20.  * Drew Eckhardt's excellent 'Generic NCR5380' sources from Linux-PC
  21.  * provided much of the inspiration and some of the code for this
  22.  * driver. Everything I know about Amiga DMA was gleaned from careful
  23.  * reading of Hamish Mcdonald's original wd33c93 driver; in fact, I
  24.  * borrowed shamelessly from all over that source. Thanks Hamish!
  25.  *
  26.  * _This_ driver is (I feel) an improvement over the old one in
  27.  * several respects:
  28.  *
  29.  *    -  Target Disconnection/Reconnection  is now supported. Any
  30.  *          system with more than one device active on the SCSI bus
  31.  *          will benefit from this. The driver defaults to what I
  32.  *          call 'adaptive disconnect' - meaning that each command
  33.  *          is evaluated individually as to whether or not it should
  34.  *          be run with the option to disconnect/reselect (if the
  35.  *          device chooses), or as a "SCSI-bus-hog".
  36.  *
  37.  *    -  Synchronous data transfers are now supported. Because of
  38.  *          a few devices that choke after telling the driver that
  39.  *          they can do sync transfers, we don't automatically use
  40.  *          this faster protocol - it can be enabled via the command-
  41.  *          line on a device-by-device basis.
  42.  *
  43.  *    -  Runtime operating parameters can now be specified through
  44.  *       the 'amiboot' or the 'insmod' command line. For amiboot do:
  45.  *          "amiboot [usual stuff] wd33c93=blah,blah,blah"
  46.  *       The defaults should be good for most people. See the comment
  47.  *       for 'setup_strings' below for more details.
  48.  *
  49.  *    -  The old driver relied exclusively on what the Western Digital
  50.  *          docs call "Combination Level 2 Commands", which are a great
  51.  *          idea in that the CPU is relieved of a lot of interrupt
  52.  *          overhead. However, by accepting a certain (user-settable)
  53.  *          amount of additional interrupts, this driver achieves
  54.  *          better control over the SCSI bus, and data transfers are
  55.  *          almost as fast while being much easier to define, track,
  56.  *          and debug.
  57.  *
  58.  *
  59.  * TODO:
  60.  *       more speed. linked commands.
  61.  *
  62.  *
  63.  * People with bug reports, wish-lists, complaints, comments,
  64.  * or improvements are asked to pah-leeez email me (John Shifflett)
  65.  * at john@geolog.com or jshiffle@netcom.com! I'm anxious to get
  66.  * this thing into as good a shape as possible, and I'm positive
  67.  * there are lots of lurking bugs and "Stupid Places".
  68.  *
  69.  * Updates:
  70.  *
  71.  * Added support for pre -A chips, which don't have advanced features
  72.  * and will generate CSR_RESEL rather than CSR_RESEL_AM.
  73.  * Richard Hirst <richard@sleepie.demon.co.uk>  August 2000
  74.  */
  75. #include <linux/config.h>
  76. #include <linux/module.h>
  77. #include <asm/system.h>
  78. #include <linux/sched.h>
  79. #include <linux/string.h>
  80. #include <linux/delay.h>
  81. #include <linux/version.h>
  82. #include <linux/init.h>
  83. #include <asm/irq.h>
  84. #include <linux/blk.h>
  85. #include "scsi.h"
  86. #include "hosts.h"
  87. #define WD33C93_VERSION    "1.25"
  88. #define WD33C93_DATE       "09/Jul/1997"
  89. /* NOTE: 1.25 for m68k is related to in2000-1.31 for x86 */
  90. /*
  91.  * Note - the following defines have been moved to 'wd33c93.h':
  92.  *
  93.  *    PROC_INTERFACE
  94.  *    PROC_STATISTICS
  95.  *    SYNC_DEBUG
  96.  *    DEBUGGING_ON
  97.  *    DEBUG_DEFAULTS
  98.  *
  99.  */
  100. #include "wd33c93.h"
  101. /*
  102.  * 'setup_strings' is a single string used to pass operating parameters and
  103.  * settings from the kernel/module command-line to the driver. 'setup_args[]'
  104.  * is an array of strings that define the compile-time default values for
  105.  * these settings. If Linux boots with an amiboot or insmod command-line,
  106.  * those settings are combined with 'setup_args[]'. Note that amiboot
  107.  * command-lines are prefixed with "wd33c93=" while insmod uses a
  108.  * "setup_strings=" prefix. The driver recognizes the following keywords
  109.  * (lower case required) and arguments:
  110.  *
  111.  * -  nosync:bitmask -bitmask is a byte where the 1st 7 bits correspond with
  112.  *                    the 7 possible SCSI devices. Set a bit to negotiate for
  113.  *                    asynchronous transfers on that device. To maintain
  114.  *                    backwards compatibility, a command-line such as
  115.  *                    "wd33c93=255" will be automatically translated to
  116.  *                    "wd33c93=nosync:0xff".
  117.  * -  nodma:x        -x = 1 to disable DMA, x = 0 to enable it. Argument is
  118.  *                    optional - if not present, same as "nodma:1".
  119.  * -  period:ns      -ns is the minimum # of nanoseconds in a SCSI data transfer
  120.  *                    period. Default is 500; acceptable values are 250 - 1000.
  121.  * -  disconnect:x   -x = 0 to never allow disconnects, 2 to always allow them.
  122.  *                    x = 1 does 'adaptive' disconnects, which is the default
  123.  *                    and generally the best choice.
  124.  * -  debug:x        -If 'DEBUGGING_ON' is defined, x is a bit mask that causes
  125.  *                    various types of debug output to printed - see the DB_xxx
  126.  *                    defines in wd33c93.h
  127.  * -  clock:x        -x = clock input in MHz for WD33c93 chip. Normal values
  128.  *                    would be from 8 through 20. Default is 8.
  129.  * -  next           -No argument. Used to separate blocks of keywords when
  130.  *                    there's more than one host adapter in the system.
  131.  *
  132.  * Syntax Notes:
  133.  * -  Numeric arguments can be decimal or the '0x' form of hex notation. There
  134.  *    _must_ be a colon between a keyword and its numeric argument, with no
  135.  *    spaces.
  136.  * -  Keywords are separated by commas, no spaces, in the standard kernel
  137.  *    command-line manner.
  138.  * -  A keyword in the 'nth' comma-separated command-line member will overwrite
  139.  *    the 'nth' element of setup_args[]. A blank command-line member (in
  140.  *    other words, a comma with no preceding keyword) will _not_ overwrite
  141.  *    the corresponding setup_args[] element.
  142.  * -  If a keyword is used more than once, the first one applies to the first
  143.  *    SCSI host found, the second to the second card, etc, unless the 'next'
  144.  *    keyword is used to change the order.
  145.  *
  146.  * Some amiboot examples (for insmod, use 'setup_strings' instead of 'wd33c93'):
  147.  * -  wd33c93=nosync:255
  148.  * -  wd33c93=nodma
  149.  * -  wd33c93=nodma:1
  150.  * -  wd33c93=disconnect:2,nosync:0x08,period:250
  151.  * -  wd33c93=debug:0x1c
  152.  */
  153. /* Normally, no defaults are specified */
  154. static char *setup_args[] =
  155.       {"","","","","","","","",""};
  156. /* filled in by 'insmod' */
  157. static char *setup_strings = 0;
  158. #ifdef MODULE_PARM
  159. MODULE_PARM(setup_strings, "s");
  160. #endif
  161. static inline uchar read_wd33c93(const wd33c93_regs regs, uchar reg_num)
  162. {
  163.    *regs.SASR = reg_num;
  164.    mb();
  165.    return(*regs.SCMD);
  166. }
  167. #define READ_AUX_STAT() (*regs.SASR)
  168. static inline void write_wd33c93(const wd33c93_regs regs, uchar reg_num,
  169.  uchar value)
  170. {
  171.    *regs.SASR = reg_num;
  172.    mb();
  173.    *regs.SCMD = value;
  174.    mb();
  175. }
  176. static inline void write_wd33c93_cmd(const wd33c93_regs regs, uchar cmd)
  177. {
  178.    *regs.SASR = WD_COMMAND;
  179.    mb();
  180.    *regs.SCMD = cmd;
  181.    mb();
  182. }
  183. static inline uchar read_1_byte(const wd33c93_regs regs)
  184. {
  185. uchar asr;
  186. uchar x = 0;
  187.    write_wd33c93(regs, WD_CONTROL, CTRL_IDI | CTRL_EDI | CTRL_POLLED);
  188.    write_wd33c93_cmd(regs, WD_CMD_TRANS_INFO|0x80);
  189.    do {
  190.       asr = READ_AUX_STAT();
  191.       if (asr & ASR_DBR)
  192.          x = read_wd33c93(regs, WD_DATA);
  193.       } while (!(asr & ASR_INT));
  194.    return x;
  195. }
  196. static void write_wd33c93_count(const wd33c93_regs regs, unsigned long value)
  197. {
  198.    *regs.SASR = WD_TRANSFER_COUNT_MSB;
  199.    mb();
  200.    *regs.SCMD = value >> 16;
  201.    *regs.SCMD = value >> 8;
  202.    *regs.SCMD = value;
  203.    mb();
  204. }
  205. static unsigned long read_wd33c93_count(const wd33c93_regs regs)
  206. {
  207. unsigned long value;
  208.    *regs.SASR = WD_TRANSFER_COUNT_MSB;
  209.    mb();
  210.    value = *regs.SCMD << 16;
  211.    value |= *regs.SCMD << 8;
  212.    value |= *regs.SCMD;
  213.    mb();
  214.    return value;
  215. }
  216. /* The 33c93 needs to be told which direction a command transfers its
  217.  * data; we use this function to figure it out. Returns true if there
  218.  * will be a DATA_OUT phase with this command, false otherwise.
  219.  * (Thanks to Joerg Dorchain for the research and suggestion.)
  220.  */
  221. static int is_dir_out(Scsi_Cmnd *cmd)
  222. {
  223.    switch (cmd->cmnd[0]) {
  224.       case WRITE_6:           case WRITE_10:          case WRITE_12:
  225.       case WRITE_LONG:        case WRITE_SAME:        case WRITE_BUFFER:
  226.       case WRITE_VERIFY:      case WRITE_VERIFY_12:      
  227.       case COMPARE:           case COPY:              case COPY_VERIFY:
  228.       case SEARCH_EQUAL:      case SEARCH_HIGH:       case SEARCH_LOW:
  229.       case SEARCH_EQUAL_12:   case SEARCH_HIGH_12:    case SEARCH_LOW_12:      
  230.       case FORMAT_UNIT:       case REASSIGN_BLOCKS:   case RESERVE:
  231.       case MODE_SELECT:       case MODE_SELECT_10:    case LOG_SELECT:
  232.       case SEND_DIAGNOSTIC:   case CHANGE_DEFINITION: case UPDATE_BLOCK:
  233.       case SET_WINDOW:        case MEDIUM_SCAN:       case SEND_VOLUME_TAG:
  234.       case 0xea:
  235.          return 1;
  236.       default:
  237.          return 0;
  238.       }
  239. }
  240. static struct sx_period sx_table[] = {
  241.    {  1, 0x20},
  242.    {252, 0x20},
  243.    {376, 0x30},
  244.    {500, 0x40},
  245.    {624, 0x50},
  246.    {752, 0x60},
  247.    {876, 0x70},
  248.    {1000,0x00},
  249.    {0,   0} };
  250. static int round_period(unsigned int period)
  251. {
  252. int x;
  253.    for (x=1; sx_table[x].period_ns; x++) {
  254.       if ((period <= sx_table[x-0].period_ns) &&
  255.           (period >  sx_table[x-1].period_ns)) {
  256.          return x;
  257.          }
  258.       }
  259.    return 7;
  260. }
  261. static uchar calc_sync_xfer(unsigned int period, unsigned int offset)
  262. {
  263. uchar result;
  264.    period *= 4;   /* convert SDTR code to ns */
  265.    result = sx_table[round_period(period)].reg_value;
  266.    result |= (offset < OPTIMUM_SX_OFF)?offset:OPTIMUM_SX_OFF;
  267.    return result;
  268. }
  269. static void wd33c93_execute(struct Scsi_Host *instance);
  270. int wd33c93_queuecommand (Scsi_Cmnd *cmd, void (*done)(Scsi_Cmnd *))
  271. {
  272.    struct WD33C93_hostdata *hostdata;
  273.    Scsi_Cmnd *tmp;
  274.    unsigned long flags;
  275.    hostdata = (struct WD33C93_hostdata *)cmd->host->hostdata;
  276. DB(DB_QUEUE_COMMAND,printk("Q-%d-%02x-%ld( ",cmd->target,cmd->cmnd[0],cmd->pid))
  277. /* Set up a few fields in the Scsi_Cmnd structure for our own use:
  278.  *  - host_scribble is the pointer to the next cmd in the input queue
  279.  *  - scsi_done points to the routine we call when a cmd is finished
  280.  *  - result is what you'd expect
  281.  */
  282.    cmd->host_scribble = NULL;
  283.    cmd->scsi_done = done;
  284.    cmd->result = 0;
  285. /* We use the Scsi_Pointer structure that's included with each command
  286.  * as a scratchpad (as it's intended to be used!). The handy thing about
  287.  * the SCp.xxx fields is that they're always associated with a given
  288.  * cmd, and are preserved across disconnect-reselect. This means we
  289.  * can pretty much ignore SAVE_POINTERS and RESTORE_POINTERS messages
  290.  * if we keep all the critical pointers and counters in SCp:
  291.  *  - SCp.ptr is the pointer into the RAM buffer
  292.  *  - SCp.this_residual is the size of that buffer
  293.  *  - SCp.buffer points to the current scatter-gather buffer
  294.  *  - SCp.buffers_residual tells us how many S.G. buffers there are
  295.  *  - SCp.have_data_in is not used
  296.  *  - SCp.sent_command is not used
  297.  *  - SCp.phase records this command's SRCID_ER bit setting
  298.  */
  299.    if (cmd->use_sg) {
  300.       cmd->SCp.buffer = (struct scatterlist *)cmd->buffer;
  301.       cmd->SCp.buffers_residual = cmd->use_sg - 1;
  302.       cmd->SCp.ptr = (char *)cmd->SCp.buffer->address;
  303.       cmd->SCp.this_residual = cmd->SCp.buffer->length;
  304.       }
  305.    else {
  306.       cmd->SCp.buffer = NULL;
  307.       cmd->SCp.buffers_residual = 0;
  308.       cmd->SCp.ptr = (char *)cmd->request_buffer;
  309.       cmd->SCp.this_residual = cmd->request_bufflen;
  310.       }
  311. /* WD docs state that at the conclusion of a "LEVEL2" command, the
  312.  * status byte can be retrieved from the LUN register. Apparently,
  313.  * this is the case only for *uninterrupted* LEVEL2 commands! If
  314.  * there are any unexpected phases entered, even if they are 100%
  315.  * legal (different devices may choose to do things differently),
  316.  * the LEVEL2 command sequence is exited. This often occurs prior
  317.  * to receiving the status byte, in which case the driver does a
  318.  * status phase interrupt and gets the status byte on its own.
  319.  * While such a command can then be "resumed" (ie restarted to
  320.  * finish up as a LEVEL2 command), the LUN register will NOT be
  321.  * a valid status byte at the command's conclusion, and we must
  322.  * use the byte obtained during the earlier interrupt. Here, we
  323.  * preset SCp.Status to an illegal value (0xff) so that when
  324.  * this command finally completes, we can tell where the actual
  325.  * status byte is stored.
  326.  */
  327.    cmd->SCp.Status = ILLEGAL_STATUS_BYTE;
  328.    /*
  329.     * Add the cmd to the end of 'input_Q'. Note that REQUEST SENSE
  330.     * commands are added to the head of the queue so that the desired
  331.     * sense data is not lost before REQUEST_SENSE executes.
  332.     */
  333.    save_flags(flags);
  334.    cli();
  335.    if (!(hostdata->input_Q) || (cmd->cmnd[0] == REQUEST_SENSE)) {
  336.       cmd->host_scribble = (uchar *)hostdata->input_Q;
  337.       hostdata->input_Q = cmd;
  338.       }
  339.    else {   /* find the end of the queue */
  340.       for (tmp=(Scsi_Cmnd *)hostdata->input_Q; tmp->host_scribble;
  341.             tmp=(Scsi_Cmnd *)tmp->host_scribble)
  342.          ;
  343.       tmp->host_scribble = (uchar *)cmd;
  344.       }
  345. /* We know that there's at least one command in 'input_Q' now.
  346.  * Go see if any of them are runnable!
  347.  */
  348.    wd33c93_execute(cmd->host);
  349. DB(DB_QUEUE_COMMAND,printk(")Q-%ld ",cmd->pid))
  350.    restore_flags(flags);
  351.    return 0;
  352. }
  353. /*
  354.  * This routine attempts to start a scsi command. If the host_card is
  355.  * already connected, we give up immediately. Otherwise, look through
  356.  * the input_Q, using the first command we find that's intended
  357.  * for a currently non-busy target/lun.
  358.  *
  359.  * wd33c93_execute() is always called with interrupts disabled or from
  360.  * the wd33c93_intr itself, which means that a wd33c93 interrupt
  361.  * cannot occur while we are in here.
  362.  */
  363. static void wd33c93_execute (struct Scsi_Host *instance)
  364. {
  365. struct WD33C93_hostdata *hostdata = (struct WD33C93_hostdata *)instance->hostdata;
  366. const wd33c93_regs regs = hostdata->regs;
  367. Scsi_Cmnd *cmd, *prev;
  368. int i;
  369. DB(DB_EXECUTE,printk("EX("))
  370.    if (hostdata->selecting || hostdata->connected) {
  371. DB(DB_EXECUTE,printk(")EX-0 "))
  372.       return;
  373.       }
  374.     /*
  375.      * Search through the input_Q for a command destined
  376.      * for an idle target/lun.
  377.      */
  378.    cmd = (Scsi_Cmnd *)hostdata->input_Q;
  379.    prev = 0;
  380.    while (cmd) {
  381.       if (!(hostdata->busy[cmd->target] & (1 << cmd->lun)))
  382.          break;
  383.       prev = cmd;
  384.       cmd = (Scsi_Cmnd *)cmd->host_scribble;
  385.       }
  386.    /* quit if queue empty or all possible targets are busy */
  387.    if (!cmd) {
  388. DB(DB_EXECUTE,printk(")EX-1 "))
  389.       return;
  390.       }
  391.    /*  remove command from queue */
  392.    
  393.    if (prev)
  394.       prev->host_scribble = cmd->host_scribble;
  395.    else
  396.       hostdata->input_Q = (Scsi_Cmnd *)cmd->host_scribble;
  397. #ifdef PROC_STATISTICS
  398.    hostdata->cmd_cnt[cmd->target]++;
  399. #endif
  400.    /*
  401.     * Start the selection process
  402.     */
  403.    if (is_dir_out(cmd))
  404.       write_wd33c93(regs, WD_DESTINATION_ID, cmd->target);
  405.    else
  406.       write_wd33c93(regs, WD_DESTINATION_ID, cmd->target | DSTID_DPD);
  407. /* Now we need to figure out whether or not this command is a good
  408.  * candidate for disconnect/reselect. We guess to the best of our
  409.  * ability, based on a set of hierarchical rules. When several
  410.  * devices are operating simultaneously, disconnects are usually
  411.  * an advantage. In a single device system, or if only 1 device
  412.  * is being accessed, transfers usually go faster if disconnects
  413.  * are not allowed:
  414.  *
  415.  * + Commands should NEVER disconnect if hostdata->disconnect =
  416.  *   DIS_NEVER (this holds for tape drives also), and ALWAYS
  417.  *   disconnect if hostdata->disconnect = DIS_ALWAYS.
  418.  * + Tape drive commands should always be allowed to disconnect.
  419.  * + Disconnect should be allowed if disconnected_Q isn't empty.
  420.  * + Commands should NOT disconnect if input_Q is empty.
  421.  * + Disconnect should be allowed if there are commands in input_Q
  422.  *   for a different target/lun. In this case, the other commands
  423.  *   should be made disconnect-able, if not already.
  424.  *
  425.  * I know, I know - this code would flunk me out of any
  426.  * "C Programming 101" class ever offered. But it's easy
  427.  * to change around and experiment with for now.
  428.  */
  429.    cmd->SCp.phase = 0;  /* assume no disconnect */
  430.    if (hostdata->disconnect == DIS_NEVER)
  431.       goto no;
  432.    if (hostdata->disconnect == DIS_ALWAYS)
  433.       goto yes;
  434.    if (cmd->device->type == 1)   /* tape drive? */
  435.       goto yes;
  436.    if (hostdata->disconnected_Q) /* other commands disconnected? */
  437.       goto yes;
  438.    if (!(hostdata->input_Q))     /* input_Q empty? */
  439.       goto no;
  440.    for (prev=(Scsi_Cmnd *)hostdata->input_Q; prev;
  441.          prev=(Scsi_Cmnd *)prev->host_scribble) {
  442.       if ((prev->target != cmd->target) || (prev->lun != cmd->lun)) {
  443.          for (prev=(Scsi_Cmnd *)hostdata->input_Q; prev;
  444.                prev=(Scsi_Cmnd *)prev->host_scribble)
  445.             prev->SCp.phase = 1;
  446.          goto yes;
  447.          }
  448.       }
  449.    goto no;
  450. yes:
  451.    cmd->SCp.phase = 1;
  452. #ifdef PROC_STATISTICS
  453.    hostdata->disc_allowed_cnt[cmd->target]++;
  454. #endif
  455. no:
  456.    write_wd33c93(regs, WD_SOURCE_ID, ((cmd->SCp.phase)?SRCID_ER:0));
  457.    write_wd33c93(regs, WD_TARGET_LUN, cmd->lun);
  458.    write_wd33c93(regs, WD_SYNCHRONOUS_TRANSFER,hostdata->sync_xfer[cmd->target]);
  459.    hostdata->busy[cmd->target] |= (1 << cmd->lun);
  460.    if ((hostdata->level2 == L2_NONE) ||
  461.        (hostdata->sync_stat[cmd->target] == SS_UNSET)) {
  462.          /*
  463.           * Do a 'Select-With-ATN' command. This will end with
  464.           * one of the following interrupts:
  465.           *    CSR_RESEL_AM:  failure - can try again later.
  466.           *    CSR_TIMEOUT:   failure - give up.
  467.           *    CSR_SELECT:    success - proceed.
  468.           */
  469.       hostdata->selecting = cmd;
  470. /* Every target has its own synchronous transfer setting, kept in the
  471.  * sync_xfer array, and a corresponding status byte in sync_stat[].
  472.  * Each target's sync_stat[] entry is initialized to SX_UNSET, and its
  473.  * sync_xfer[] entry is initialized to the default/safe value. SS_UNSET
  474.  * means that the parameters are undetermined as yet, and that we
  475.  * need to send an SDTR message to this device after selection is
  476.  * complete: We set SS_FIRST to tell the interrupt routine to do so.
  477.  * If we've been asked not to try synchronous transfers on this
  478.  * target (and _all_ luns within it), we'll still send the SDTR message
  479.  * later, but at that time we'll negotiate for async by specifying a
  480.  * sync fifo depth of 0.
  481.  */
  482.       if (hostdata->sync_stat[cmd->target] == SS_UNSET)
  483.             hostdata->sync_stat[cmd->target] = SS_FIRST;
  484.       hostdata->state = S_SELECTING;
  485.       write_wd33c93_count(regs, 0); /* guarantee a DATA_PHASE interrupt */
  486.       write_wd33c93_cmd(regs, WD_CMD_SEL_ATN);
  487.       }
  488.    else {
  489.          /*
  490.           * Do a 'Select-With-ATN-Xfer' command. This will end with
  491.           * one of the following interrupts:
  492.           *    CSR_RESEL_AM:  failure - can try again later.
  493.           *    CSR_TIMEOUT:   failure - give up.
  494.           *    anything else: success - proceed.
  495.           */
  496.       hostdata->connected = cmd;
  497.       write_wd33c93(regs, WD_COMMAND_PHASE, 0);
  498.    /* copy command_descriptor_block into WD chip
  499.     * (take advantage of auto-incrementing)
  500.     */
  501.       *regs.SASR = WD_CDB_1;
  502.       for (i=0; i<cmd->cmd_len; i++)
  503.          *regs.SCMD = cmd->cmnd[i];
  504.    /* The wd33c93 only knows about Group 0, 1, and 5 commands when
  505.     * it's doing a 'select-and-transfer'. To be safe, we write the
  506.     * size of the CDB into the OWN_ID register for every case. This
  507.     * way there won't be problems with vendor-unique, audio, etc.
  508.     */
  509.       write_wd33c93(regs, WD_OWN_ID, cmd->cmd_len);
  510.    /* When doing a non-disconnect command with DMA, we can save
  511.     * ourselves a DATA phase interrupt later by setting everything
  512.     * up ahead of time.
  513.     */
  514.       if ((cmd->SCp.phase == 0) && (hostdata->no_dma == 0)) {
  515.          if (hostdata->dma_setup(cmd,
  516.                      (is_dir_out(cmd))?DATA_OUT_DIR:DATA_IN_DIR))
  517.             write_wd33c93_count(regs, 0); /* guarantee a DATA_PHASE interrupt */
  518.          else {
  519.             write_wd33c93_count(regs, cmd->SCp.this_residual);
  520.             write_wd33c93(regs, WD_CONTROL, CTRL_IDI | CTRL_EDI | CTRL_DMA);
  521.             hostdata->dma = D_DMA_RUNNING;
  522.             }
  523.          }
  524.       else
  525.          write_wd33c93_count(regs, 0); /* guarantee a DATA_PHASE interrupt */
  526.       hostdata->state = S_RUNNING_LEVEL2;
  527.       write_wd33c93_cmd(regs, WD_CMD_SEL_ATN_XFER);
  528.       }
  529.    /*
  530.     * Since the SCSI bus can handle only 1 connection at a time,
  531.     * we get out of here now. If the selection fails, or when
  532.     * the command disconnects, we'll come back to this routine
  533.     * to search the input_Q again...
  534.     */
  535.       
  536. DB(DB_EXECUTE,printk("%s%ld)EX-2 ",(cmd->SCp.phase)?"d:":"",cmd->pid))
  537. }
  538. static void transfer_pio(const wd33c93_regs regs, uchar *buf, int cnt,
  539.  int data_in_dir, struct WD33C93_hostdata *hostdata)
  540. {
  541. uchar asr;
  542. DB(DB_TRANSFER,printk("(%p,%d,%s:",buf,cnt,data_in_dir?"in":"out"))
  543.    write_wd33c93(regs, WD_CONTROL, CTRL_IDI | CTRL_EDI | CTRL_POLLED);
  544.    write_wd33c93_count(regs, cnt);
  545.    write_wd33c93_cmd(regs, WD_CMD_TRANS_INFO);
  546.    if (data_in_dir) {
  547.       do {
  548.          asr = READ_AUX_STAT();
  549.          if (asr & ASR_DBR)
  550.             *buf++ = read_wd33c93(regs, WD_DATA);
  551.          } while (!(asr & ASR_INT));
  552.       }
  553.    else {
  554.       do {
  555.          asr = READ_AUX_STAT();
  556.          if (asr & ASR_DBR)
  557.             write_wd33c93(regs, WD_DATA, *buf++);
  558.          } while (!(asr & ASR_INT));
  559.       }
  560.    /* Note: we are returning with the interrupt UN-cleared.
  561.    * Since (presumably) an entire I/O operation has
  562.    * completed, the bus phase is probably different, and
  563.    * the interrupt routine will discover this when it
  564.    * responds to the uncleared int.
  565.    */
  566. }
  567. static void transfer_bytes(const wd33c93_regs regs, Scsi_Cmnd *cmd,
  568.    int data_in_dir)
  569. {
  570. struct WD33C93_hostdata *hostdata;
  571. unsigned long length;
  572.    hostdata = (struct WD33C93_hostdata *)cmd->host->hostdata;
  573. /* Normally, you'd expect 'this_residual' to be non-zero here.
  574.  * In a series of scatter-gather transfers, however, this
  575.  * routine will usually be called with 'this_residual' equal
  576.  * to 0 and 'buffers_residual' non-zero. This means that a
  577.  * previous transfer completed, clearing 'this_residual', and
  578.  * now we need to setup the next scatter-gather buffer as the
  579.  * source or destination for THIS transfer.
  580.  */
  581.    if (!cmd->SCp.this_residual && cmd->SCp.buffers_residual) {
  582.       ++cmd->SCp.buffer;
  583.       --cmd->SCp.buffers_residual;
  584.       cmd->SCp.this_residual = cmd->SCp.buffer->length;
  585.       cmd->SCp.ptr = cmd->SCp.buffer->address;
  586.       }
  587.    write_wd33c93(regs, WD_SYNCHRONOUS_TRANSFER,hostdata->sync_xfer[cmd->target]);
  588. /* 'hostdata->no_dma' is TRUE if we don't even want to try DMA.
  589.  * Update 'this_residual' and 'ptr' after 'transfer_pio()' returns.
  590.  */
  591.    if (hostdata->no_dma)
  592.       goto use_transfer_pio;
  593. /* 'dma_setup()' will return TRUE if we can't do DMA.
  594.  * Update 'this_residual' and 'ptr' after 'transfer_pio()' returns.
  595.  */
  596.    else if (hostdata->dma_setup(cmd, data_in_dir)) {
  597. use_transfer_pio:
  598. #ifdef PROC_STATISTICS
  599.       hostdata->pio_cnt++;
  600. #endif
  601.       transfer_pio(regs, (uchar *)cmd->SCp.ptr, cmd->SCp.this_residual,
  602.                          data_in_dir, hostdata);
  603.       length = cmd->SCp.this_residual;
  604.       cmd->SCp.this_residual = read_wd33c93_count(regs);
  605.       cmd->SCp.ptr += (length - cmd->SCp.this_residual);
  606.       }
  607. /* We are able to do DMA (in fact, the Amiga hardware is
  608.  * already going!), so start up the wd33c93 in DMA mode.
  609.  * We set 'hostdata->dma' = D_DMA_RUNNING so that when the
  610.  * transfer completes and causes an interrupt, we're
  611.  * reminded to tell the Amiga to shut down its end. We'll
  612.  * postpone the updating of 'this_residual' and 'ptr'
  613.  * until then.
  614.  */
  615.    else {
  616. #ifdef PROC_STATISTICS
  617.       hostdata->dma_cnt++;
  618. #endif
  619.       write_wd33c93(regs, WD_CONTROL, CTRL_IDI | CTRL_EDI | CTRL_DMA);
  620.       write_wd33c93_count(regs, cmd->SCp.this_residual);
  621.       if ((hostdata->level2 >= L2_DATA) ||
  622.           (hostdata->level2 == L2_BASIC && cmd->SCp.phase == 0)) {
  623.          write_wd33c93(regs, WD_COMMAND_PHASE, 0x45);
  624.          write_wd33c93_cmd(regs, WD_CMD_SEL_ATN_XFER);
  625.          hostdata->state = S_RUNNING_LEVEL2;
  626.          }
  627.       else
  628.          write_wd33c93_cmd(regs, WD_CMD_TRANS_INFO);
  629.       hostdata->dma = D_DMA_RUNNING;
  630.       }
  631. }
  632. void wd33c93_intr (struct Scsi_Host *instance)
  633. {
  634. struct WD33C93_hostdata *hostdata = (struct WD33C93_hostdata *)instance->hostdata;
  635. const wd33c93_regs regs = hostdata->regs;
  636. Scsi_Cmnd *patch, *cmd;
  637. uchar asr, sr, phs, id, lun, *ucp, msg;
  638. unsigned long length, flags;
  639.    asr = READ_AUX_STAT();
  640.    if (!(asr & ASR_INT) || (asr & ASR_BSY))
  641.       return;
  642.    save_flags(flags);
  643. #ifdef PROC_STATISTICS
  644.    hostdata->int_cnt++;
  645. #endif
  646.    cmd = (Scsi_Cmnd *)hostdata->connected;   /* assume we're connected */
  647.    sr = read_wd33c93(regs, WD_SCSI_STATUS);  /* clear the interrupt */
  648.    phs = read_wd33c93(regs, WD_COMMAND_PHASE);
  649. DB(DB_INTR,printk("{%02x:%02x-",asr,sr))
  650. /* After starting a DMA transfer, the next interrupt
  651.  * is guaranteed to be in response to completion of
  652.  * the transfer. Since the Amiga DMA hardware runs in
  653.  * in an open-ended fashion, it needs to be told when
  654.  * to stop; do that here if D_DMA_RUNNING is true.
  655.  * Also, we have to update 'this_residual' and 'ptr'
  656.  * based on the contents of the TRANSFER_COUNT register,
  657.  * in case the device decided to do an intermediate
  658.  * disconnect (a device may do this if it has to do a
  659.  * seek, or just to be nice and let other devices have
  660.  * some bus time during long transfers). After doing
  661.  * whatever is needed, we go on and service the WD3393
  662.  * interrupt normally.
  663.  */
  664.    if (hostdata->dma == D_DMA_RUNNING) {
  665. DB(DB_TRANSFER,printk("[%p/%d:",cmd->SCp.ptr,cmd->SCp.this_residual))
  666.       hostdata->dma_stop(cmd->host, cmd, 1);
  667.       hostdata->dma = D_DMA_OFF;
  668.       length = cmd->SCp.this_residual;
  669.       cmd->SCp.this_residual = read_wd33c93_count(regs);
  670.       cmd->SCp.ptr += (length - cmd->SCp.this_residual);
  671. DB(DB_TRANSFER,printk("%p/%d]",cmd->SCp.ptr,cmd->SCp.this_residual))
  672.       }
  673. /* Respond to the specific WD3393 interrupt - there are quite a few! */
  674.    switch (sr) {
  675.       case CSR_TIMEOUT:
  676. DB(DB_INTR,printk("TIMEOUT"))
  677.          if (hostdata->state == S_RUNNING_LEVEL2)
  678.             hostdata->connected = NULL;
  679.          else {
  680.             cmd = (Scsi_Cmnd *)hostdata->selecting;   /* get a valid cmd */
  681.             hostdata->selecting = NULL;
  682.             }
  683.          cmd->result = DID_NO_CONNECT << 16;
  684.          hostdata->busy[cmd->target] &= ~(1 << cmd->lun);
  685.          hostdata->state = S_UNCONNECTED;
  686.          cmd->scsi_done(cmd);
  687.     /* From esp.c:
  688.      * There is a window of time within the scsi_done() path
  689.      * of execution where interrupts are turned back on full
  690.      * blast and left that way.  During that time we could
  691.      * reconnect to a disconnected command, then we'd bomb
  692.      * out below.  We could also end up executing two commands
  693.      * at _once_.  ...just so you know why the restore_flags()
  694.      * is here...
  695.      */
  696.     restore_flags(flags);
  697. /* We are not connected to a target - check to see if there
  698.  * are commands waiting to be executed.
  699.  */
  700.          wd33c93_execute(instance);
  701.          break;
  702. /* Note: this interrupt should not occur in a LEVEL2 command */
  703.       case CSR_SELECT:
  704. DB(DB_INTR,printk("SELECT"))
  705.          hostdata->connected = cmd = (Scsi_Cmnd *)hostdata->selecting;
  706.          hostdata->selecting = NULL;
  707.       /* construct an IDENTIFY message with correct disconnect bit */
  708.          hostdata->outgoing_msg[0] = (0x80 | 0x00 | cmd->lun);
  709.          if (cmd->SCp.phase)
  710.             hostdata->outgoing_msg[0] |= 0x40;
  711.          if (hostdata->sync_stat[cmd->target] == SS_FIRST) {
  712. #ifdef SYNC_DEBUG
  713. printk(" sending SDTR ");
  714. #endif
  715.             hostdata->sync_stat[cmd->target] = SS_WAITING;
  716. /* Tack on a 2nd message to ask about synchronous transfers. If we've
  717.  * been asked to do only asynchronous transfers on this device, we
  718.  * request a fifo depth of 0, which is equivalent to async - should
  719.  * solve the problems some people have had with GVP's Guru ROM.
  720.  */
  721.             hostdata->outgoing_msg[1] = EXTENDED_MESSAGE;
  722.             hostdata->outgoing_msg[2] = 3;
  723.             hostdata->outgoing_msg[3] = EXTENDED_SDTR;
  724.             if (hostdata->no_sync & (1 << cmd->target)) {
  725.                hostdata->outgoing_msg[4] = hostdata->default_sx_per/4;
  726.                hostdata->outgoing_msg[5] = 0;
  727.                }
  728.             else {
  729.             hostdata->outgoing_msg[4] = OPTIMUM_SX_PER/4;
  730.             hostdata->outgoing_msg[5] = OPTIMUM_SX_OFF;
  731.                }
  732.             hostdata->outgoing_len = 6;
  733.             }
  734.          else
  735.             hostdata->outgoing_len = 1;
  736.          hostdata->state = S_CONNECTED;
  737.          break;
  738.       case CSR_XFER_DONE|PHS_DATA_IN:
  739.       case CSR_UNEXP    |PHS_DATA_IN:
  740.       case CSR_SRV_REQ  |PHS_DATA_IN:
  741. DB(DB_INTR,printk("IN-%d.%d",cmd->SCp.this_residual,cmd->SCp.buffers_residual))
  742.          transfer_bytes(regs, cmd, DATA_IN_DIR);
  743.          if (hostdata->state != S_RUNNING_LEVEL2)
  744.             hostdata->state = S_CONNECTED;
  745.          break;
  746.       case CSR_XFER_DONE|PHS_DATA_OUT:
  747.       case CSR_UNEXP    |PHS_DATA_OUT:
  748.       case CSR_SRV_REQ  |PHS_DATA_OUT:
  749. DB(DB_INTR,printk("OUT-%d.%d",cmd->SCp.this_residual,cmd->SCp.buffers_residual))
  750.          transfer_bytes(regs, cmd, DATA_OUT_DIR);
  751.          if (hostdata->state != S_RUNNING_LEVEL2)
  752.             hostdata->state = S_CONNECTED;
  753.          break;
  754. /* Note: this interrupt should not occur in a LEVEL2 command */
  755.       case CSR_XFER_DONE|PHS_COMMAND:
  756.       case CSR_UNEXP    |PHS_COMMAND:
  757.       case CSR_SRV_REQ  |PHS_COMMAND:
  758. DB(DB_INTR,printk("CMND-%02x,%ld",cmd->cmnd[0],cmd->pid))
  759.          transfer_pio(regs, cmd->cmnd, cmd->cmd_len, DATA_OUT_DIR, hostdata);
  760.          hostdata->state = S_CONNECTED;
  761.          break;
  762.       case CSR_XFER_DONE|PHS_STATUS:
  763.       case CSR_UNEXP    |PHS_STATUS:
  764.       case CSR_SRV_REQ  |PHS_STATUS:
  765. DB(DB_INTR,printk("STATUS="))
  766.          cmd->SCp.Status = read_1_byte(regs);
  767. DB(DB_INTR,printk("%02x",cmd->SCp.Status))
  768.          if (hostdata->level2 >= L2_BASIC) {
  769.             sr = read_wd33c93(regs, WD_SCSI_STATUS);  /* clear interrupt */
  770.             hostdata->state = S_RUNNING_LEVEL2;
  771.             write_wd33c93(regs, WD_COMMAND_PHASE, 0x50);
  772.             write_wd33c93_cmd(regs, WD_CMD_SEL_ATN_XFER);
  773.             }
  774.          else {
  775.             hostdata->state = S_CONNECTED;
  776.             }
  777.          break;
  778.       case CSR_XFER_DONE|PHS_MESS_IN:
  779.       case CSR_UNEXP    |PHS_MESS_IN:
  780.       case CSR_SRV_REQ  |PHS_MESS_IN:
  781. DB(DB_INTR,printk("MSG_IN="))
  782.          msg = read_1_byte(regs);
  783.          sr = read_wd33c93(regs, WD_SCSI_STATUS);  /* clear interrupt */
  784.          hostdata->incoming_msg[hostdata->incoming_ptr] = msg;
  785.          if (hostdata->incoming_msg[0] == EXTENDED_MESSAGE)
  786.             msg = EXTENDED_MESSAGE;
  787.          else
  788.             hostdata->incoming_ptr = 0;
  789.          cmd->SCp.Message = msg;
  790.          switch (msg) {
  791.             case COMMAND_COMPLETE:
  792. DB(DB_INTR,printk("CCMP-%ld",cmd->pid))
  793.                write_wd33c93_cmd(regs, WD_CMD_NEGATE_ACK);
  794.                hostdata->state = S_PRE_CMP_DISC;
  795.                break;
  796.             case SAVE_POINTERS:
  797. DB(DB_INTR,printk("SDP"))
  798.                write_wd33c93_cmd(regs, WD_CMD_NEGATE_ACK);
  799.                hostdata->state = S_CONNECTED;
  800.                break;
  801.             case RESTORE_POINTERS:
  802. DB(DB_INTR,printk("RDP"))
  803.                if (hostdata->level2 >= L2_BASIC) {
  804.                   write_wd33c93(regs, WD_COMMAND_PHASE, 0x45);
  805.                   write_wd33c93_cmd(regs, WD_CMD_SEL_ATN_XFER);
  806.                   hostdata->state = S_RUNNING_LEVEL2;
  807.                   }
  808.                else {
  809.                   write_wd33c93_cmd(regs, WD_CMD_NEGATE_ACK);
  810.                   hostdata->state = S_CONNECTED;
  811.                   }
  812.                break;
  813.             case DISCONNECT:
  814. DB(DB_INTR,printk("DIS"))
  815.                cmd->device->disconnect = 1;
  816.                write_wd33c93_cmd(regs, WD_CMD_NEGATE_ACK);
  817.                hostdata->state = S_PRE_TMP_DISC;
  818.                break;
  819.             case MESSAGE_REJECT:
  820. DB(DB_INTR,printk("REJ"))
  821. #ifdef SYNC_DEBUG
  822. printk("-REJ-");
  823. #endif
  824.                if (hostdata->sync_stat[cmd->target] == SS_WAITING)
  825.                   hostdata->sync_stat[cmd->target] = SS_SET;
  826.                write_wd33c93_cmd(regs, WD_CMD_NEGATE_ACK);
  827.                hostdata->state = S_CONNECTED;
  828.                break;
  829.             case EXTENDED_MESSAGE:
  830. DB(DB_INTR,printk("EXT"))
  831.                ucp = hostdata->incoming_msg;
  832. #ifdef SYNC_DEBUG
  833. printk("%02x",ucp[hostdata->incoming_ptr]);
  834. #endif
  835.          /* Is this the last byte of the extended message? */
  836.                if ((hostdata->incoming_ptr >= 2) &&
  837.                    (hostdata->incoming_ptr == (ucp[1] + 1))) {
  838.                   switch (ucp[2]) {   /* what's the EXTENDED code? */
  839.                      case EXTENDED_SDTR:
  840.                         id = calc_sync_xfer(ucp[3],ucp[4]);
  841.                         if (hostdata->sync_stat[cmd->target] != SS_WAITING) {
  842. /* A device has sent an unsolicited SDTR message; rather than go
  843.  * through the effort of decoding it and then figuring out what
  844.  * our reply should be, we're just gonna say that we have a
  845.  * synchronous fifo depth of 0. This will result in asynchronous
  846.  * transfers - not ideal but so much easier.
  847.  * Actually, this is OK because it assures us that if we don't
  848.  * specifically ask for sync transfers, we won't do any.
  849.  */
  850.                            write_wd33c93_cmd(regs, WD_CMD_ASSERT_ATN); /* want MESS_OUT */
  851.                            hostdata->outgoing_msg[0] = EXTENDED_MESSAGE;
  852.                            hostdata->outgoing_msg[1] = 3;
  853.                            hostdata->outgoing_msg[2] = EXTENDED_SDTR;
  854.                            hostdata->outgoing_msg[3] = hostdata->default_sx_per/4;
  855.                            hostdata->outgoing_msg[4] = 0;
  856.                            hostdata->outgoing_len = 5;
  857.                            hostdata->sync_xfer[cmd->target] =
  858.                                        calc_sync_xfer(hostdata->default_sx_per/4,0);
  859.                            }
  860.                         else {
  861.                            hostdata->sync_xfer[cmd->target] = id;
  862.                            }
  863. #ifdef SYNC_DEBUG
  864. printk("sync_xfer=%02x",hostdata->sync_xfer[cmd->target]);
  865. #endif
  866.                         hostdata->sync_stat[cmd->target] = SS_SET;
  867.                         write_wd33c93_cmd(regs, WD_CMD_NEGATE_ACK);
  868.                         hostdata->state = S_CONNECTED;
  869.                         break;
  870.                      case EXTENDED_WDTR:
  871.                         write_wd33c93_cmd(regs, WD_CMD_ASSERT_ATN); /* want MESS_OUT */
  872.                         printk("sending WDTR ");
  873.                         hostdata->outgoing_msg[0] = EXTENDED_MESSAGE;
  874.                         hostdata->outgoing_msg[1] = 2;
  875.                         hostdata->outgoing_msg[2] = EXTENDED_WDTR;
  876.                         hostdata->outgoing_msg[3] = 0;   /* 8 bit transfer width */
  877.                         hostdata->outgoing_len = 4;
  878.                         write_wd33c93_cmd(regs, WD_CMD_NEGATE_ACK);
  879.                         hostdata->state = S_CONNECTED;
  880.                         break;
  881.                      default:
  882.                         write_wd33c93_cmd(regs, WD_CMD_ASSERT_ATN); /* want MESS_OUT */
  883.                         printk("Rejecting Unknown Extended Message(%02x). ",ucp[2]);
  884.                         hostdata->outgoing_msg[0] = MESSAGE_REJECT;
  885.                         hostdata->outgoing_len = 1;
  886.                         write_wd33c93_cmd(regs, WD_CMD_NEGATE_ACK);
  887.                         hostdata->state = S_CONNECTED;
  888.                         break;
  889.                      }
  890.                   hostdata->incoming_ptr = 0;
  891.                   }
  892.          /* We need to read more MESS_IN bytes for the extended message */
  893.                else {
  894.                   hostdata->incoming_ptr++;
  895.                   write_wd33c93_cmd(regs, WD_CMD_NEGATE_ACK);
  896.                   hostdata->state = S_CONNECTED;
  897.                   }
  898.                break;
  899.             default:
  900.                printk("Rejecting Unknown Message(%02x) ",msg);
  901.                write_wd33c93_cmd(regs, WD_CMD_ASSERT_ATN); /* want MESS_OUT */
  902.                hostdata->outgoing_msg[0] = MESSAGE_REJECT;
  903.                hostdata->outgoing_len = 1;
  904.                write_wd33c93_cmd(regs, WD_CMD_NEGATE_ACK);
  905.                hostdata->state = S_CONNECTED;
  906.             }
  907.          restore_flags(flags);
  908.          break;
  909. /* Note: this interrupt will occur only after a LEVEL2 command */
  910.       case CSR_SEL_XFER_DONE:
  911. /* Make sure that reselection is enabled at this point - it may
  912.  * have been turned off for the command that just completed.
  913.  */
  914.          write_wd33c93(regs, WD_SOURCE_ID, SRCID_ER);
  915.          if (phs == 0x60) {
  916. DB(DB_INTR,printk("SX-DONE-%ld",cmd->pid))
  917.             cmd->SCp.Message = COMMAND_COMPLETE;
  918.             lun = read_wd33c93(regs, WD_TARGET_LUN);
  919. DB(DB_INTR,printk(":%d.%d",cmd->SCp.Status,lun))
  920.             hostdata->connected = NULL;
  921.             hostdata->busy[cmd->target] &= ~(1 << cmd->lun);
  922.             hostdata->state = S_UNCONNECTED;
  923.             if (cmd->SCp.Status == ILLEGAL_STATUS_BYTE)
  924.                cmd->SCp.Status = lun;
  925.             if (cmd->cmnd[0] == REQUEST_SENSE && cmd->SCp.Status != GOOD)
  926.                cmd->result = (cmd->result & 0x00ffff) | (DID_ERROR << 16);
  927.             else
  928.                cmd->result = cmd->SCp.Status | (cmd->SCp.Message << 8);
  929.             cmd->scsi_done(cmd);
  930. /* We are no longer  connected to a target - check to see if
  931.  * there are commands waiting to be executed.
  932.  */
  933.        restore_flags(flags);
  934.             wd33c93_execute(instance);
  935.             }
  936.          else {
  937.             printk("%02x:%02x:%02x-%ld: Unknown SEL_XFER_DONE phase!!---",asr,sr,phs,cmd->pid);
  938.             }
  939.          break;
  940. /* Note: this interrupt will occur only after a LEVEL2 command */
  941.       case CSR_SDP:
  942. DB(DB_INTR,printk("SDP"))
  943.             hostdata->state = S_RUNNING_LEVEL2;
  944.             write_wd33c93(regs, WD_COMMAND_PHASE, 0x41);
  945.             write_wd33c93_cmd(regs, WD_CMD_SEL_ATN_XFER);
  946.          break;
  947.       case CSR_XFER_DONE|PHS_MESS_OUT:
  948.       case CSR_UNEXP    |PHS_MESS_OUT:
  949.       case CSR_SRV_REQ  |PHS_MESS_OUT:
  950. DB(DB_INTR,printk("MSG_OUT="))
  951. /* To get here, we've probably requested MESSAGE_OUT and have
  952.  * already put the correct bytes in outgoing_msg[] and filled
  953.  * in outgoing_len. We simply send them out to the SCSI bus.
  954.  * Sometimes we get MESSAGE_OUT phase when we're not expecting
  955.  * it - like when our SDTR message is rejected by a target. Some
  956.  * targets send the REJECT before receiving all of the extended
  957.  * message, and then seem to go back to MESSAGE_OUT for a byte
  958.  * or two. Not sure why, or if I'm doing something wrong to
  959.  * cause this to happen. Regardless, it seems that sending
  960.  * NOP messages in these situations results in no harm and
  961.  * makes everyone happy.
  962.  */
  963.          if (hostdata->outgoing_len == 0) {
  964.             hostdata->outgoing_len = 1;
  965.             hostdata->outgoing_msg[0] = NOP;
  966.             }
  967.          transfer_pio(regs, hostdata->outgoing_msg, hostdata->outgoing_len,
  968.                             DATA_OUT_DIR, hostdata);
  969. DB(DB_INTR,printk("%02x",hostdata->outgoing_msg[0]))
  970.          hostdata->outgoing_len = 0;
  971.          hostdata->state = S_CONNECTED;
  972.          break;
  973.       case CSR_UNEXP_DISC:
  974. /* I think I've seen this after a request-sense that was in response
  975.  * to an error condition, but not sure. We certainly need to do
  976.  * something when we get this interrupt - the question is 'what?'.
  977.  * Let's think positively, and assume some command has finished
  978.  * in a legal manner (like a command that provokes a request-sense),
  979.  * so we treat it as a normal command-complete-disconnect.
  980.  */
  981. /* Make sure that reselection is enabled at this point - it may
  982.  * have been turned off for the command that just completed.
  983.  */
  984.          write_wd33c93(regs, WD_SOURCE_ID, SRCID_ER);
  985.          if (cmd == NULL) {
  986.             printk(" - Already disconnected! ");
  987.             hostdata->state = S_UNCONNECTED;
  988.             return;
  989.             }
  990. DB(DB_INTR,printk("UNEXP_DISC-%ld",cmd->pid))
  991.          hostdata->connected = NULL;
  992.          hostdata->busy[cmd->target] &= ~(1 << cmd->lun);
  993.          hostdata->state = S_UNCONNECTED;
  994.          if (cmd->cmnd[0] == REQUEST_SENSE && cmd->SCp.Status != GOOD)
  995.             cmd->result = (cmd->result & 0x00ffff) | (DID_ERROR << 16);
  996.          else
  997.             cmd->result = cmd->SCp.Status | (cmd->SCp.Message << 8);
  998.          cmd->scsi_done(cmd);
  999. /* We are no longer connected to a target - check to see if
  1000.  * there are commands waiting to be executed.
  1001.  */
  1002.     /* look above for comments on scsi_done() */
  1003.     restore_flags(flags);
  1004.          wd33c93_execute(instance);
  1005.          break;
  1006.       case CSR_DISC:
  1007. /* Make sure that reselection is enabled at this point - it may
  1008.  * have been turned off for the command that just completed.
  1009.  */
  1010.          write_wd33c93(regs, WD_SOURCE_ID, SRCID_ER);
  1011. DB(DB_INTR,printk("DISC-%ld",cmd->pid))
  1012.          if (cmd == NULL) {
  1013.             printk(" - Already disconnected! ");
  1014.             hostdata->state = S_UNCONNECTED;
  1015.             }
  1016.          switch (hostdata->state) {
  1017.             case S_PRE_CMP_DISC:
  1018.                hostdata->connected = NULL;
  1019.                hostdata->busy[cmd->target] &= ~(1 << cmd->lun);
  1020.                hostdata->state = S_UNCONNECTED;
  1021. DB(DB_INTR,printk(":%d",cmd->SCp.Status))
  1022.                if (cmd->cmnd[0] == REQUEST_SENSE && cmd->SCp.Status != GOOD)
  1023.                   cmd->result = (cmd->result & 0x00ffff) | (DID_ERROR << 16);
  1024.                else
  1025.                   cmd->result = cmd->SCp.Status | (cmd->SCp.Message << 8);
  1026.                cmd->scsi_done(cmd);
  1027.           restore_flags(flags);
  1028.                break;
  1029.             case S_PRE_TMP_DISC:
  1030.             case S_RUNNING_LEVEL2:
  1031.                cmd->host_scribble = (uchar *)hostdata->disconnected_Q;
  1032.                hostdata->disconnected_Q = cmd;
  1033.                hostdata->connected = NULL;
  1034.                hostdata->state = S_UNCONNECTED;
  1035. #ifdef PROC_STATISTICS
  1036.                hostdata->disc_done_cnt[cmd->target]++;
  1037. #endif
  1038.                break;
  1039.             default:
  1040.                printk("*** Unexpected DISCONNECT interrupt! ***");
  1041.                hostdata->state = S_UNCONNECTED;
  1042.             }
  1043. /* We are no longer connected to a target - check to see if
  1044.  * there are commands waiting to be executed.
  1045.  */
  1046.          wd33c93_execute(instance);
  1047.          break;
  1048.       case CSR_RESEL_AM:
  1049.       case CSR_RESEL:
  1050. DB(DB_INTR,printk("RESEL%s", sr == CSR_RESEL_AM ? "_AM" : ""))
  1051.    /* Old chips (pre -A ???) don't have advanced features and will
  1052.     * generate CSR_RESEL.  In that case we have to extract the LUN the
  1053.     * hard way (see below).
  1054.     * First we have to make sure this reselection didn't
  1055.     * happen during Arbitration/Selection of some other device.
  1056.     * If yes, put losing command back on top of input_Q.
  1057.     */
  1058.          if (hostdata->level2 <= L2_NONE) {
  1059.             if (hostdata->selecting) {
  1060.                cmd = (Scsi_Cmnd *)hostdata->selecting;
  1061.                hostdata->selecting = NULL;
  1062.                hostdata->busy[cmd->target] &= ~(1 << cmd->lun);
  1063.                cmd->host_scribble = (uchar *)hostdata->input_Q;
  1064.                hostdata->input_Q = cmd;
  1065.                }
  1066.             }
  1067.          else {
  1068.             if (cmd) {
  1069.                if (phs == 0x00) {
  1070.                   hostdata->busy[cmd->target] &= ~(1 << cmd->lun);
  1071.                   cmd->host_scribble = (uchar *)hostdata->input_Q;
  1072.                   hostdata->input_Q = cmd;
  1073.                   }
  1074.                else {
  1075.                   printk("---%02x:%02x:%02x-TROUBLE: Intrusive ReSelect!---",asr,sr,phs);
  1076.                   while (1)
  1077.                      printk("r");
  1078.                   }
  1079.                }
  1080.             }
  1081.    /* OK - find out which device reselected us. */
  1082.          id = read_wd33c93(regs, WD_SOURCE_ID);
  1083.          id &= SRCID_MASK;
  1084.    /* and extract the lun from the ID message. (Note that we don't
  1085.     * bother to check for a valid message here - I guess this is
  1086.     * not the right way to go, but...)
  1087.     */
  1088.          if (sr == CSR_RESEL_AM) {
  1089.             lun = read_wd33c93(regs, WD_DATA);
  1090.             if (hostdata->level2 < L2_RESELECT)
  1091.                write_wd33c93_cmd(regs, WD_CMD_NEGATE_ACK);
  1092.             lun &= 7;
  1093.          }
  1094.          else {
  1095.             /* Old chip; wait for msgin phase to pick up the LUN. */
  1096.             for (lun = 255; lun; lun--) {
  1097.                if ((asr = READ_AUX_STAT()) & ASR_INT)
  1098.                   break;
  1099.                udelay(10);
  1100.             }
  1101.             if (!(asr & ASR_INT)) {
  1102.                printk("wd33c93: Reselected without IDENTIFYn");
  1103.                lun = 0;
  1104.             }
  1105.             else {
  1106.                /* Verify this is a change to MSG_IN and read the message */
  1107.                sr = read_wd33c93(regs, WD_SCSI_STATUS);
  1108.                if (sr == (CSR_ABORT   | PHS_MESS_IN) ||
  1109.                    sr == (CSR_UNEXP   | PHS_MESS_IN) ||
  1110.                    sr == (CSR_SRV_REQ | PHS_MESS_IN)) {
  1111.                   /* Got MSG_IN, grab target LUN */
  1112.                   lun = read_1_byte(regs);
  1113.                   /* Now we expect a 'paused with ACK asserted' int.. */
  1114.                   asr = READ_AUX_STAT();
  1115.                   if (!(asr & ASR_INT)) {
  1116.                      udelay(10);
  1117.                      asr = READ_AUX_STAT();
  1118.                      if (!(asr & ASR_INT))
  1119.                         printk("wd33c93: No int after LUN on RESEL (%02x)n",
  1120.                               asr);
  1121.                   }
  1122.                   sr = read_wd33c93(regs, WD_SCSI_STATUS);
  1123.                   if (sr != CSR_MSGIN)
  1124.                      printk("wd33c93: Not paused with ACK on RESEL (%02x)n",
  1125.                            sr);
  1126.                   lun &= 7;
  1127.                   write_wd33c93_cmd(regs, WD_CMD_NEGATE_ACK);
  1128.                }
  1129.                else {
  1130.                   printk("wd33c93: Not MSG_IN on reselect (%02x)n", sr);
  1131.                   lun = 0;
  1132.                }
  1133.             }
  1134.          }
  1135.    /* Now we look for the command that's reconnecting. */
  1136.          cmd = (Scsi_Cmnd *)hostdata->disconnected_Q;
  1137.          patch = NULL;
  1138.          while (cmd) {
  1139.             if (id == cmd->target && lun == cmd->lun)
  1140.                break;
  1141.             patch = cmd;
  1142.             cmd = (Scsi_Cmnd *)cmd->host_scribble;
  1143.             }
  1144.    /* Hmm. Couldn't find a valid command.... What to do? */
  1145.          if (!cmd) {
  1146.             printk("---TROUBLE: target %d.%d not in disconnect queue---",id,lun);
  1147.             return;
  1148.             }
  1149.    /* Ok, found the command - now start it up again. */
  1150.          if (patch)
  1151.             patch->host_scribble = cmd->host_scribble;
  1152.          else
  1153.             hostdata->disconnected_Q = (Scsi_Cmnd *)cmd->host_scribble;
  1154.          hostdata->connected = cmd;
  1155.    /* We don't need to worry about 'initialize_SCp()' or 'hostdata->busy[]'
  1156.     * because these things are preserved over a disconnect.
  1157.     * But we DO need to fix the DPD bit so it's correct for this command.
  1158.     */
  1159.          if (is_dir_out(cmd))
  1160.             write_wd33c93(regs, WD_DESTINATION_ID, cmd->target);
  1161.          else
  1162.             write_wd33c93(regs, WD_DESTINATION_ID, cmd->target | DSTID_DPD);
  1163.          if (hostdata->level2 >= L2_RESELECT) {
  1164.             write_wd33c93_count(regs, 0);  /* we want a DATA_PHASE interrupt */
  1165.             write_wd33c93(regs, WD_COMMAND_PHASE, 0x45);
  1166.             write_wd33c93_cmd(regs, WD_CMD_SEL_ATN_XFER);
  1167.             hostdata->state = S_RUNNING_LEVEL2;
  1168.             }
  1169.          else
  1170.             hostdata->state = S_CONNECTED;
  1171. DB(DB_INTR,printk("-%ld",cmd->pid))
  1172.          break;
  1173.          
  1174.       default:
  1175.          printk("--UNKNOWN INTERRUPT:%02x:%02x:%02x--",asr,sr,phs);
  1176.       }
  1177. DB(DB_INTR,printk("} "))
  1178. }
  1179. static void reset_wd33c93(struct Scsi_Host *instance)
  1180. {
  1181. struct WD33C93_hostdata *hostdata = (struct WD33C93_hostdata *)instance->hostdata;
  1182. const wd33c93_regs regs = hostdata->regs;
  1183. uchar sr;
  1184.    write_wd33c93(regs, WD_OWN_ID, OWNID_EAF | OWNID_RAF |
  1185.                  instance->this_id | hostdata->clock_freq);
  1186.    write_wd33c93(regs, WD_CONTROL, CTRL_IDI | CTRL_EDI | CTRL_POLLED);
  1187.    write_wd33c93(regs, WD_SYNCHRONOUS_TRANSFER,
  1188.                  calc_sync_xfer(hostdata->default_sx_per/4,DEFAULT_SX_OFF));
  1189.    write_wd33c93(regs, WD_COMMAND, WD_CMD_RESET);
  1190. #ifdef CONFIG_MVME147_SCSI
  1191.    udelay(25); /* The old wd33c93 on MVME147 needs this, at least */
  1192. #endif
  1193.    while (!(READ_AUX_STAT() & ASR_INT))
  1194.       ;
  1195.    sr = read_wd33c93(regs, WD_SCSI_STATUS);
  1196.    hostdata->microcode = read_wd33c93(regs, WD_CDB_1);
  1197.    if (sr == 0x00)
  1198.       hostdata->chip = C_WD33C93;
  1199.    else if (sr == 0x01) {
  1200.       write_wd33c93(regs, WD_QUEUE_TAG, 0xa5);  /* any random number */
  1201.       sr = read_wd33c93(regs, WD_QUEUE_TAG);
  1202.       if (sr == 0xa5) {
  1203.          hostdata->chip = C_WD33C93B;
  1204.          write_wd33c93(regs, WD_QUEUE_TAG, 0);
  1205.          }
  1206.       else
  1207.          hostdata->chip = C_WD33C93A;
  1208.       }
  1209.    else
  1210.       hostdata->chip = C_UNKNOWN_CHIP;
  1211.    write_wd33c93(regs, WD_TIMEOUT_PERIOD, TIMEOUT_PERIOD_VALUE);
  1212.    write_wd33c93(regs, WD_CONTROL, CTRL_IDI | CTRL_EDI | CTRL_POLLED);
  1213. }
  1214. int wd33c93_reset(Scsi_Cmnd *SCpnt, unsigned int reset_flags)
  1215. {
  1216. struct Scsi_Host *instance;
  1217. struct WD33C93_hostdata *hostdata;
  1218. int i;
  1219.    instance = SCpnt->host;
  1220.    hostdata = (struct WD33C93_hostdata *)instance->hostdata;
  1221.    printk("scsi%d: reset. ", instance->host_no);
  1222.    disable_irq(instance->irq);
  1223.    ((struct WD33C93_hostdata *)instance->hostdata)->dma_stop(instance,NULL,0);
  1224.    for (i = 0; i < 8; i++) {
  1225.       hostdata->busy[i] = 0;
  1226.       hostdata->sync_xfer[i] = calc_sync_xfer(DEFAULT_SX_PER/4,DEFAULT_SX_OFF);
  1227.       hostdata->sync_stat[i] = SS_UNSET;  /* using default sync values */
  1228.       }
  1229.    hostdata->input_Q = NULL;
  1230.    hostdata->selecting = NULL;
  1231.    hostdata->connected = NULL;
  1232.    hostdata->disconnected_Q = NULL;
  1233.    hostdata->state = S_UNCONNECTED;
  1234.    hostdata->dma = D_DMA_OFF;
  1235.    hostdata->incoming_ptr = 0;
  1236.    hostdata->outgoing_len = 0;
  1237.    reset_wd33c93(instance);
  1238.    SCpnt->result = DID_RESET << 16;
  1239.    enable_irq(instance->irq);
  1240.    return 0;
  1241. }
  1242. int wd33c93_abort (Scsi_Cmnd *cmd)
  1243. {
  1244. struct Scsi_Host *instance;
  1245. struct WD33C93_hostdata *hostdata;
  1246. wd33c93_regs regs;
  1247. Scsi_Cmnd *tmp, *prev;
  1248.    disable_irq(cmd->host->irq);
  1249.    instance = cmd->host;
  1250.    hostdata = (struct WD33C93_hostdata *)instance->hostdata;
  1251.    regs = hostdata->regs;
  1252. /*
  1253.  * Case 1 : If the command hasn't been issued yet, we simply remove it
  1254.  *     from the input_Q.
  1255.  */
  1256.    tmp = (Scsi_Cmnd *)hostdata->input_Q;
  1257.    prev = 0;
  1258.    while (tmp) {
  1259.       if (tmp == cmd) {
  1260.          if (prev)
  1261.             prev->host_scribble = cmd->host_scribble;
  1262.  else
  1263.             hostdata->input_Q = (Scsi_Cmnd *)cmd->host_scribble;
  1264.          cmd->host_scribble = NULL;
  1265.          cmd->result = DID_ABORT << 16;
  1266.          printk("scsi%d: Abort - removing command %ld from input_Q. ",
  1267.            instance->host_no, cmd->pid);
  1268.     enable_irq(cmd->host->irq);
  1269.          cmd->scsi_done(cmd);
  1270.          return SCSI_ABORT_SUCCESS;
  1271.          }
  1272.       prev = tmp;
  1273.       tmp = (Scsi_Cmnd *)tmp->host_scribble;
  1274.       }
  1275. /*
  1276.  * Case 2 : If the command is connected, we're going to fail the abort
  1277.  *     and let the high level SCSI driver retry at a later time or
  1278.  *     issue a reset.
  1279.  *
  1280.  *     Timeouts, and therefore aborted commands, will be highly unlikely
  1281.  *     and handling them cleanly in this situation would make the common
  1282.  *     case of noresets less efficient, and would pollute our code.  So,
  1283.  *     we fail.
  1284.  */
  1285.    if (hostdata->connected == cmd) {
  1286.       uchar sr, asr;
  1287.       unsigned long timeout;
  1288.       printk("scsi%d: Aborting connected command %ld - ",
  1289.               instance->host_no, cmd->pid);
  1290.       printk("stopping DMA - ");
  1291.       if (hostdata->dma == D_DMA_RUNNING) {
  1292.          hostdata->dma_stop(instance, cmd, 0);
  1293.          hostdata->dma = D_DMA_OFF;
  1294.          }
  1295.       printk("sending wd33c93 ABORT command - ");
  1296.       write_wd33c93(regs, WD_CONTROL, CTRL_IDI | CTRL_EDI | CTRL_POLLED);
  1297.       write_wd33c93_cmd(regs, WD_CMD_ABORT);
  1298. /* Now we have to attempt to flush out the FIFO... */
  1299.       printk("flushing fifo - ");
  1300.       timeout = 1000000;
  1301.       do {
  1302.          asr = READ_AUX_STAT();
  1303.          if (asr & ASR_DBR)
  1304.             read_wd33c93(regs, WD_DATA);
  1305.          } while (!(asr & ASR_INT) && timeout-- > 0);
  1306.       sr = read_wd33c93(regs, WD_SCSI_STATUS);
  1307.       printk("asr=%02x, sr=%02x, %ld bytes un-transferred (timeout=%ld) - ",
  1308.              asr, sr, read_wd33c93_count(regs), timeout);
  1309.    /*
  1310.     * Abort command processed.
  1311.     * Still connected.
  1312.     * We must disconnect.
  1313.     */
  1314.       printk("sending wd33c93 DISCONNECT command - ");
  1315.       write_wd33c93_cmd(regs, WD_CMD_DISCONNECT);
  1316.       timeout = 1000000;
  1317.       asr = READ_AUX_STAT();
  1318.       while ((asr & ASR_CIP) && timeout-- > 0)
  1319.          asr = READ_AUX_STAT();
  1320.       sr = read_wd33c93(regs, WD_SCSI_STATUS);
  1321.       printk("asr=%02x, sr=%02x.",asr,sr);
  1322.       hostdata->busy[cmd->target] &= ~(1 << cmd->lun);
  1323.       hostdata->connected = NULL;
  1324.       hostdata->state = S_UNCONNECTED;
  1325.       cmd->result = DID_ABORT << 16;
  1326. /*      sti();*/
  1327.       wd33c93_execute (instance);
  1328.       enable_irq(cmd->host->irq);
  1329.       cmd->scsi_done(cmd);
  1330.       return SCSI_ABORT_SUCCESS;
  1331.       }
  1332. /*
  1333.  * Case 3: If the command is currently disconnected from the bus,
  1334.  * we're not going to expend much effort here: Let's just return
  1335.  * an ABORT_SNOOZE and hope for the best...
  1336.  */
  1337.    tmp = (Scsi_Cmnd *)hostdata->disconnected_Q;
  1338.    while (tmp) {
  1339.       if (tmp == cmd) {
  1340.          printk("scsi%d: Abort - command %ld found on disconnected_Q - ",
  1341.                  instance->host_no, cmd->pid);
  1342.          printk("returning ABORT_SNOOZE. ");
  1343.     enable_irq(cmd->host->irq);
  1344.          return SCSI_ABORT_SNOOZE;
  1345.          }
  1346.       tmp = (Scsi_Cmnd *)tmp->host_scribble;
  1347.       }
  1348. /*
  1349.  * Case 4 : If we reached this point, the command was not found in any of
  1350.  *     the queues.
  1351.  *
  1352.  * We probably reached this point because of an unlikely race condition
  1353.  * between the command completing successfully and the abortion code,
  1354.  * so we won't panic, but we will notify the user in case something really
  1355.  * broke.
  1356.  */
  1357. /*   sti();*/
  1358.    wd33c93_execute (instance);
  1359.    enable_irq(cmd->host->irq);
  1360.    printk("scsi%d: warning : SCSI command probably completed successfully"
  1361.       "         before abortion. ", instance->host_no);
  1362.    return SCSI_ABORT_NOT_RUNNING;
  1363. }
  1364. #define MAX_WD33C93_HOSTS 4
  1365. #define MAX_SETUP_ARGS ((int)(sizeof(setup_args) / sizeof(char *)))
  1366. #define SETUP_BUFFER_SIZE 200
  1367. static char setup_buffer[SETUP_BUFFER_SIZE];
  1368. static char setup_used[MAX_SETUP_ARGS];
  1369. static int done_setup = 0;
  1370. int wd33c93_setup (char *str)
  1371. {
  1372.    int i;
  1373.    char *p1,*p2;
  1374.    /* The kernel does some processing of the command-line before calling
  1375.     * this function: If it begins with any decimal or hex number arguments,
  1376.     * ints[0] = how many numbers found and ints[1] through [n] are the values
  1377.     * themselves. str points to where the non-numeric arguments (if any)
  1378.     * start: We do our own parsing of those. We construct synthetic 'nosync'
  1379.     * keywords out of numeric args (to maintain compatibility with older
  1380.     * versions) and then add the rest of the arguments.
  1381.     */
  1382.    p1 = setup_buffer;
  1383.    *p1 = '';
  1384. #if 0
  1385. /*
  1386.  * Old style command line arguments are now dead
  1387.  */
  1388.    if (ints[0]) {
  1389.       for (i=0; i<ints[0]; i++) {
  1390.          x = vsprintf(p1,"nosync:0x%02x,",&(ints[i+1]));
  1391.          p1 += x;
  1392.          }
  1393.       }
  1394. #endif
  1395.    if (str)
  1396.       strncpy(p1, str, SETUP_BUFFER_SIZE - strlen(setup_buffer));
  1397.    setup_buffer[SETUP_BUFFER_SIZE - 1] = '';
  1398.    p1 = setup_buffer;
  1399.    i = 0;
  1400.    while (*p1 && (i < MAX_SETUP_ARGS)) {
  1401.       p2 = strchr(p1, ',');
  1402.       if (p2) {
  1403.          *p2 = '';
  1404.          if (p1 != p2)
  1405.             setup_args[i] = p1;
  1406.          p1 = p2 + 1;
  1407.          i++;
  1408.          }
  1409.       else {
  1410.          setup_args[i] = p1;
  1411.          break;
  1412.          }
  1413.       }
  1414.    for (i=0; i<MAX_SETUP_ARGS; i++)
  1415.       setup_used[i] = 0;
  1416.    done_setup = 1;
  1417.    return 1;
  1418. }
  1419. __setup("wd33c93", wd33c93_setup);
  1420. /* check_setup_args() returns index if key found, 0 if not
  1421.  */
  1422. static int check_setup_args(char *key, int *flags, int *val, char *buf)
  1423. {
  1424. int x;
  1425. char *cp;
  1426.    for  (x=0; x<MAX_SETUP_ARGS; x++) {
  1427.       if (setup_used[x])
  1428.          continue;
  1429.       if (!strncmp(setup_args[x], key, strlen(key)))
  1430.          break;
  1431.       if (!strncmp(setup_args[x], "next", strlen("next")))
  1432.          return 0;
  1433.       }
  1434.    if (x == MAX_SETUP_ARGS)
  1435.       return 0;
  1436.    setup_used[x] = 1;
  1437.    cp = setup_args[x] + strlen(key);
  1438.    *val = -1;
  1439.    if (*cp != ':')
  1440.       return ++x;
  1441.    cp++;
  1442.    if ((*cp >= '0') && (*cp <= '9')) {
  1443.       *val = simple_strtoul(cp,NULL,0);
  1444.       }
  1445.    return ++x;
  1446. }
  1447. void wd33c93_init(struct Scsi_Host *instance, const wd33c93_regs regs,
  1448.   dma_setup_t setup, dma_stop_t stop, int clock_freq)
  1449. {
  1450. struct WD33C93_hostdata *hostdata;
  1451. int i;
  1452. int flags;
  1453. int val;
  1454. char buf[32];
  1455.    if (!done_setup && setup_strings)
  1456.       wd33c93_setup(setup_strings);
  1457.    hostdata = (struct WD33C93_hostdata *)instance->hostdata;
  1458.    hostdata->regs = regs;
  1459.    hostdata->clock_freq = clock_freq;
  1460.    hostdata->dma_setup = setup;
  1461.    hostdata->dma_stop = stop;
  1462.    hostdata->dma_bounce_buffer = NULL;
  1463.    hostdata->dma_bounce_len = 0;
  1464.    for (i = 0; i < 8; i++) {
  1465.       hostdata->busy[i] = 0;
  1466.       hostdata->sync_xfer[i] = calc_sync_xfer(DEFAULT_SX_PER/4,DEFAULT_SX_OFF);
  1467.       hostdata->sync_stat[i] = SS_UNSET;  /* using default sync values */
  1468. #ifdef PROC_STATISTICS
  1469.       hostdata->cmd_cnt[i] = 0;
  1470.       hostdata->disc_allowed_cnt[i] = 0;
  1471.       hostdata->disc_done_cnt[i] = 0;
  1472. #endif
  1473.       }
  1474.    hostdata->input_Q = NULL;
  1475.    hostdata->selecting = NULL;
  1476.    hostdata->connected = NULL;
  1477.    hostdata->disconnected_Q = NULL;
  1478.    hostdata->state = S_UNCONNECTED;
  1479.    hostdata->dma = D_DMA_OFF;
  1480.    hostdata->level2 = L2_BASIC;
  1481.    hostdata->disconnect = DIS_ADAPTIVE;
  1482.    hostdata->args = DEBUG_DEFAULTS;
  1483.    hostdata->incoming_ptr = 0;
  1484.    hostdata->outgoing_len = 0;
  1485.    hostdata->default_sx_per = DEFAULT_SX_PER;
  1486.    hostdata->no_sync = 0xff;     /* sync defaults to off */
  1487.    hostdata->no_dma = 0;         /* default is DMA enabled */
  1488. #ifdef PROC_INTERFACE
  1489.    hostdata->proc = PR_VERSION|PR_INFO|PR_STATISTICS|
  1490.                     PR_CONNECTED|PR_INPUTQ|PR_DISCQ|
  1491.                     PR_STOP;
  1492. #ifdef PROC_STATISTICS
  1493.    hostdata->dma_cnt = 0;
  1494.    hostdata->pio_cnt = 0;
  1495.    hostdata->int_cnt = 0;
  1496. #endif
  1497. #endif
  1498.    if (check_setup_args("nosync",&flags,&val,buf))
  1499.       hostdata->no_sync = val;
  1500.    if (check_setup_args("nodma",&flags,&val,buf))
  1501.       hostdata->no_dma = (val == -1) ? 1 : val;
  1502.    if (check_setup_args("period",&flags,&val,buf))
  1503.       hostdata->default_sx_per = sx_table[round_period((unsigned int)val)].period_ns;
  1504.    if (check_setup_args("disconnect",&flags,&val,buf)) {
  1505.       if ((val >= DIS_NEVER) && (val <= DIS_ALWAYS))
  1506.          hostdata->disconnect = val;
  1507.       else
  1508.          hostdata->disconnect = DIS_ADAPTIVE;
  1509.       }
  1510.    if (check_setup_args("level2",&flags,&val,buf))
  1511.       hostdata->level2 = val;
  1512.    if (check_setup_args("debug",&flags,&val,buf))
  1513.       hostdata->args = val & DB_MASK;
  1514.    if (check_setup_args("clock",&flags,&val,buf)) {
  1515.       if (val>7 && val<11)
  1516.          val = WD33C93_FS_8_10;
  1517.       else if (val>11 && val<16)
  1518.          val = WD33C93_FS_12_15;
  1519.       else if (val>15 && val<21)
  1520.          val = WD33C93_FS_16_20;
  1521.       else
  1522.          val = WD33C93_FS_8_10;
  1523.       hostdata->clock_freq = val;
  1524.       }
  1525.    if ((i = check_setup_args("next",&flags,&val,buf))) {
  1526.       while (i)
  1527.          setup_used[--i] = 1;
  1528.       }
  1529. #ifdef PROC_INTERFACE
  1530.    if (check_setup_args("proc",&flags,&val,buf))
  1531.       hostdata->proc = val;
  1532. #endif
  1533.    { unsigned long flags;
  1534.      save_flags(flags);
  1535.      cli();
  1536.      reset_wd33c93(instance);
  1537.      restore_flags(flags);
  1538.    }
  1539.    printk("wd33c93-%d: chip=%s/%d no_sync=0x%x no_dma=%d",instance->host_no,
  1540.          (hostdata->chip==C_WD33C93)?"WD33c93":
  1541.          (hostdata->chip==C_WD33C93A)?"WD33c93A":
  1542.          (hostdata->chip==C_WD33C93B)?"WD33c93B":"unknown",
  1543.          hostdata->microcode,hostdata->no_sync,hostdata->no_dma);
  1544. #ifdef DEBUGGING_ON
  1545.    printk(" debug_flags=0x%02xn",hostdata->args);
  1546. #else
  1547.    printk(" debugging=OFFn");
  1548. #endif
  1549.    printk("           setup_args=");
  1550.    for (i=0; i<MAX_SETUP_ARGS; i++)
  1551.       printk("%s,",setup_args[i]);
  1552.    printk("n");
  1553.    printk("           Version %s - %s, Compiled %s at %sn",
  1554.                WD33C93_VERSION,WD33C93_DATE,__DATE__,__TIME__);
  1555.    MOD_INC_USE_COUNT;
  1556. }
  1557. int wd33c93_proc_info(char *buf, char **start, off_t off, int len, int hn, int in)
  1558. {
  1559. #ifdef PROC_INTERFACE
  1560. char *bp;
  1561. char tbuf[128];
  1562. unsigned long flags;
  1563. struct Scsi_Host *instance;
  1564. struct WD33C93_hostdata *hd;
  1565. Scsi_Cmnd *cmd;
  1566. int x,i;
  1567. static int stop = 0;
  1568.    for (instance=scsi_hostlist; instance; instance=instance->next) {
  1569.       if (instance->host_no == hn)
  1570.          break;
  1571.       }
  1572.    if (!instance) {
  1573.       printk("*** Hmm... Can't find host #%d!n",hn);
  1574.       return (-ESRCH);
  1575.       }
  1576.    hd = (struct WD33C93_hostdata *)instance->hostdata;
  1577. /* If 'in' is TRUE we need to _read_ the proc file. We accept the following
  1578.  * keywords (same format as command-line, but only ONE per read):
  1579.  *    debug
  1580.  *    disconnect
  1581.  *    period
  1582.  *    resync
  1583.  *    proc
  1584.  *    nodma
  1585.  */
  1586.    if (in) {
  1587.       buf[len] = '';
  1588.       bp = buf;
  1589.       if (!strncmp(bp,"debug:",6)) {
  1590.          bp += 6;
  1591.          hd->args = simple_strtoul(bp,NULL,0) & DB_MASK;
  1592.          }
  1593.       else if (!strncmp(bp,"disconnect:",11)) {
  1594.          bp += 11;
  1595.          x = simple_strtoul(bp,NULL,0);
  1596.          if (x < DIS_NEVER || x > DIS_ALWAYS)
  1597.             x = DIS_ADAPTIVE;
  1598.          hd->disconnect = x;
  1599.          }
  1600.       else if (!strncmp(bp,"period:",7)) {
  1601.          bp += 7;
  1602.          x = simple_strtoul(bp,NULL,0);
  1603.          hd->default_sx_per = sx_table[round_period((unsigned int)x)].period_ns;
  1604.          }
  1605.       else if (!strncmp(bp,"resync:",7)) {
  1606.          bp += 7;
  1607.          x = simple_strtoul(bp,NULL,0);
  1608.          for (i=0; i<7; i++)
  1609.             if (x & (1<<i))
  1610.                hd->sync_stat[i] = SS_UNSET;
  1611.          }
  1612.       else if (!strncmp(bp,"proc:",5)) {
  1613.          bp += 5;
  1614.          hd->proc = simple_strtoul(bp,NULL,0);
  1615.          }
  1616.       else if (!strncmp(bp,"nodma:",6)) {
  1617.          bp += 6;
  1618.          hd->no_dma = simple_strtoul(bp,NULL,0);
  1619.          }
  1620.       else if (!strncmp(bp,"level2:",7)) {
  1621.          bp += 7;
  1622.          hd->level2 = simple_strtoul(bp,NULL,0);
  1623.          }
  1624.       return len;
  1625.       }
  1626.    save_flags(flags);
  1627.    cli();
  1628.    bp = buf;
  1629.    *bp = '';
  1630.    if (hd->proc & PR_VERSION) {
  1631.       sprintf(tbuf,"nVersion %s - %s. Compiled %s %s",
  1632.             WD33C93_VERSION,WD33C93_DATE,__DATE__,__TIME__);
  1633.       strcat(bp,tbuf);
  1634.       }
  1635.    if (hd->proc & PR_INFO) {
  1636.       sprintf(tbuf,"nclock_freq=%02x no_sync=%02x no_dma=%d",
  1637.             hd->clock_freq,hd->no_sync,hd->no_dma);
  1638.       strcat(bp,tbuf);
  1639.       strcat(bp,"nsync_xfer[] =       ");
  1640.       for (x=0; x<7; x++) {
  1641.          sprintf(tbuf,"t%02x",hd->sync_xfer[x]);
  1642.          strcat(bp,tbuf);
  1643.          }
  1644.       strcat(bp,"nsync_stat[] =       ");
  1645.       for (x=0; x<7; x++) {
  1646.          sprintf(tbuf,"t%02x",hd->sync_stat[x]);
  1647.          strcat(bp,tbuf);
  1648.          }
  1649.       }
  1650. #ifdef PROC_STATISTICS
  1651.    if (hd->proc & PR_STATISTICS) {
  1652.       strcat(bp,"ncommands issued:    ");
  1653.       for (x=0; x<7; x++) {
  1654.          sprintf(tbuf,"t%ld",hd->cmd_cnt[x]);
  1655.          strcat(bp,tbuf);
  1656.          }
  1657.       strcat(bp,"ndisconnects allowed:");
  1658.       for (x=0; x<7; x++) {
  1659.          sprintf(tbuf,"t%ld",hd->disc_allowed_cnt[x]);
  1660.          strcat(bp,tbuf);
  1661.          }
  1662.       strcat(bp,"ndisconnects done:   ");
  1663.       for (x=0; x<7; x++) {
  1664.          sprintf(tbuf,"t%ld",hd->disc_done_cnt[x]);
  1665.          strcat(bp,tbuf);
  1666.          }
  1667.       sprintf(tbuf,"ninterrupts: %ld, DATA_PHASE ints: %ld DMA, %ld PIO",
  1668.             hd->int_cnt,hd->dma_cnt,hd->pio_cnt);
  1669.       strcat(bp,tbuf);
  1670.       }
  1671. #endif
  1672.    if (hd->proc & PR_CONNECTED) {
  1673.       strcat(bp,"nconnected:     ");
  1674.       if (hd->connected) {
  1675.          cmd = (Scsi_Cmnd *)hd->connected;
  1676.          sprintf(tbuf," %ld-%d:%d(%02x)",
  1677.                cmd->pid, cmd->target, cmd->lun, cmd->cmnd[0]);
  1678.          strcat(bp,tbuf);
  1679.          }
  1680.       }
  1681.    if (hd->proc & PR_INPUTQ) {
  1682.       strcat(bp,"ninput_Q:       ");
  1683.       cmd = (Scsi_Cmnd *)hd->input_Q;
  1684.       while (cmd) {
  1685.          sprintf(tbuf," %ld-%d:%d(%02x)",
  1686.                cmd->pid, cmd->target, cmd->lun, cmd->cmnd[0]);
  1687.          strcat(bp,tbuf);
  1688.          cmd = (Scsi_Cmnd *)cmd->host_scribble;
  1689.          }
  1690.       }
  1691.    if (hd->proc & PR_DISCQ) {
  1692.       strcat(bp,"ndisconnected_Q:");
  1693.       cmd = (Scsi_Cmnd *)hd->disconnected_Q;
  1694.       while (cmd) {
  1695.          sprintf(tbuf," %ld-%d:%d(%02x)",
  1696.                cmd->pid, cmd->target, cmd->lun, cmd->cmnd[0]);
  1697.          strcat(bp,tbuf);
  1698.          cmd = (Scsi_Cmnd *)cmd->host_scribble;
  1699.          }
  1700.       }
  1701.    strcat(bp,"n");
  1702.    restore_flags(flags);
  1703.    *start = buf;
  1704.    if (stop) {
  1705.       stop = 0;
  1706.       return 0;
  1707.       }
  1708.    if (off > 0x40000)   /* ALWAYS stop after 256k bytes have been read */
  1709.       stop = 1;;
  1710.    if (hd->proc & PR_STOP)    /* stop every other time */
  1711.       stop = 1;
  1712.    return strlen(bp);
  1713. #else    /* PROC_INTERFACE */
  1714.    return 0;
  1715. #endif   /* PROC_INTERFACE */
  1716. }
  1717. #ifdef MODULE
  1718. int init_module(void) { return 0; }
  1719. void cleanup_module(void) {}
  1720. #endif
  1721. void wd33c93_release(void)
  1722. {
  1723.    MOD_DEC_USE_COUNT;
  1724. }