Annotation of Gnu-Mach/linux/src/drivers/scsi/in2000.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  *    in2000.c -  Linux device driver for the
                      3:  *                Always IN2000 ISA SCSI card.
                      4:  *
                      5:  * Copyright (c) 1996 John Shifflett, GeoLog Consulting
                      6:  *    [email protected]
                      7:  *    [email protected]
                      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 provided
                     21:  * much of the inspiration and some of the code for this driver.
                     22:  * The Linux IN2000 driver distributed in the Linux kernels through
                     23:  * version 1.2.13 was an extremely valuable reference on the arcane
                     24:  * (and still mysterious) workings of the IN2000's fifo. It also
                     25:  * is where I lifted in2000_biosparam(), the gist of the card
                     26:  * detection scheme, and other bits of code. Many thanks to the
                     27:  * talented and courageous people who wrote, contributed to, and
                     28:  * maintained that driver (including Brad McLean, Shaun Savage,
                     29:  * Bill Earnest, Larry Doolittle, Roger Sunshine, John Luckey,
                     30:  * Matt Postiff, Peter Lu, [email protected], and Eric
                     31:  * Youngdale). I should also mention the driver written by
                     32:  * Hamish Macdonald for the (GASP!) Amiga A2091 card, included
                     33:  * in the Linux-m68k distribution; it gave me a good initial
                     34:  * understanding of the proper way to run a WD33c93 chip, and I
                     35:  * ended up stealing lots of code from it.
                     36:  *
                     37:  * _This_ driver is (I feel) an improvement over the old one in
                     38:  * several respects:
                     39:  *    -  All problems relating to the data size of a SCSI request are
                     40:  *          gone (as far as I know). The old driver couldn't handle
                     41:  *          swapping to partitions because that involved 4k blocks, nor
                     42:  *          could it deal with the st.c tape driver unmodified, because
                     43:  *          that usually involved 4k - 32k blocks. The old driver never
                     44:  *          quite got away from a morbid dependence on 2k block sizes -
                     45:  *          which of course is the size of the card's fifo.
                     46:  *
                     47:  *    -  Target Disconnection/Reconnection is now supported. Any
                     48:  *          system with more than one device active on the SCSI bus
                     49:  *          will benefit from this. The driver defaults to what I'm
                     50:  *          calling 'adaptive disconnect' - meaning that each command
                     51:  *          is evaluated individually as to whether or not it should
                     52:  *          be run with the option to disconnect/reselect (if the
                     53:  *          device chooses), or as a "SCSI-bus-hog".
                     54:  *
                     55:  *    -  Synchronous data transfers are now supported. Because there
                     56:  *          are a few devices (and many improperly terminated systems)
                     57:  *          that choke when doing sync, the default is sync DISABLED
                     58:  *          for all devices. This faster protocol can (and should!)
                     59:  *          be enabled on selected devices via the command-line.
                     60:  *
                     61:  *    -  Runtime operating parameters can now be specified through
                     62:  *       either the LILO or the 'insmod' command line. For LILO do:
                     63:  *          "in2000=blah,blah,blah"
                     64:  *       and with insmod go like:
                     65:  *          "insmod /usr/src/linux/modules/in2000.o setup_strings=blah,blah"
                     66:  *       The defaults should be good for most people. See the comment
                     67:  *       for 'setup_strings' below for more details.
                     68:  *
                     69:  *    -  The old driver relied exclusively on what the Western Digital
                     70:  *          docs call "Combination Level 2 Commands", which are a great
                     71:  *          idea in that the CPU is relieved of a lot of interrupt
                     72:  *          overhead. However, by accepting a certain (user-settable)
                     73:  *          amount of additional interrupts, this driver achieves
                     74:  *          better control over the SCSI bus, and data transfers are
                     75:  *          almost as fast while being much easier to define, track,
                     76:  *          and debug.
                     77:  *
                     78:  *    -  You can force detection of a card whose BIOS has been disabled.
                     79:  *
                     80:  *    -  Multiple IN2000 cards might almost be supported. I've tried to
                     81:  *       keep it in mind, but have no way to test...
                     82:  *
                     83:  *
                     84:  * TODO:
                     85:  *       tagged queuing. multiple cards.
                     86:  *
                     87:  *
                     88:  * NOTE:
                     89:  *       When using this or any other SCSI driver as a module, you'll
                     90:  *       find that with the stock kernel, at most _two_ SCSI hard
                     91:  *       drives will be linked into the device list (ie, usable).
                     92:  *       If your IN2000 card has more than 2 disks on its bus, you
                     93:  *       might want to change the define of 'SD_EXTRA_DEVS' in the
                     94:  *       'hosts.h' file from 2 to whatever is appropriate. It took
                     95:  *       me a while to track down this surprisingly obscure and
                     96:  *       undocumented little "feature".
                     97:  *
                     98:  *
                     99:  * People with bug reports, wish-lists, complaints, comments,
                    100:  * or improvements are asked to pah-leeez email me (John Shifflett)
                    101:  * at [email protected] or [email protected]! I'm anxious to get
                    102:  * this thing into as good a shape as possible, and I'm positive
                    103:  * there are lots of lurking bugs and "Stupid Places".
                    104:  *
                    105:  */
                    106: 
                    107: #include <linux/module.h>
                    108: 
                    109: #include <asm/system.h>
                    110: #include <linux/sched.h>
                    111: #include <linux/string.h>
                    112: #include <linux/delay.h>
                    113: #include <linux/proc_fs.h>
                    114: #include <asm/io.h>
                    115: #include <linux/ioport.h>
                    116: #include <linux/blkdev.h>
                    117: 
                    118: #include <linux/blk.h>
                    119: #include <linux/stat.h>
                    120: 
                    121: #include "scsi.h"
                    122: #include "sd.h"
                    123: #include "hosts.h"
                    124: 
                    125: #define IN2000_VERSION    "1.33"
                    126: #define IN2000_DATE       "26/August/1998"
                    127: 
                    128: #include "in2000.h"
                    129: 
                    130: 
                    131: /*
                    132:  * 'setup_strings' is a single string used to pass operating parameters and
                    133:  * settings from the kernel/module command-line to the driver. 'setup_args[]'
                    134:  * is an array of strings that define the compile-time default values for
                    135:  * these settings. If Linux boots with a LILO or insmod command-line, those
                    136:  * settings are combined with 'setup_args[]'. Note that LILO command-lines
                    137:  * are prefixed with "in2000=" while insmod uses a "setup_strings=" prefix.
                    138:  * The driver recognizes the following keywords (lower case required) and
                    139:  * arguments:
                    140:  *
                    141:  * -  ioport:addr    -Where addr is IO address of a (usually ROM-less) card.
                    142:  * -  noreset        -No optional args. Prevents SCSI bus reset at boot time.
                    143:  * -  nosync:x       -x is a bitmask where the 1st 7 bits correspond with
                    144:  *                    the 7 possible SCSI devices (bit 0 for device #0, etc).
                    145:  *                    Set a bit to PREVENT sync negotiation on that device.
                    146:  *                    The driver default is sync DISABLED on all devices.
                    147:  * -  period:ns      -ns is the minimum # of nanoseconds in a SCSI data transfer
                    148:  *                    period. Default is 500; acceptable values are 250 - 1000.
                    149:  * -  disconnect:x   -x = 0 to never allow disconnects, 2 to always allow them.
                    150:  *                    x = 1 does 'adaptive' disconnects, which is the default
                    151:  *                    and generally the best choice.
                    152:  * -  debug:x        -If 'DEBUGGING_ON' is defined, x is a bitmask that causes
                    153:  *                    various types of debug output to printed - see the DB_xxx
                    154:  *                    defines in in2000.h
                    155:  * -  proc:x         -If 'PROC_INTERFACE' is defined, x is a bitmask that
                    156:  *                    determines how the /proc interface works and what it
                    157:  *                    does - see the PR_xxx defines in in2000.h
                    158:  *
                    159:  * Syntax Notes:
                    160:  * -  Numeric arguments can be decimal or the '0x' form of hex notation. There
                    161:  *    _must_ be a colon between a keyword and its numeric argument, with no
                    162:  *    spaces.
                    163:  * -  Keywords are separated by commas, no spaces, in the standard kernel
                    164:  *    command-line manner.
                    165:  * -  A keyword in the 'nth' comma-separated command-line member will overwrite
                    166:  *    the 'nth' element of setup_args[]. A blank command-line member (in
                    167:  *    other words, a comma with no preceding keyword) will _not_ overwrite
                    168:  *    the corresponding setup_args[] element.
                    169:  *
                    170:  * A few LILO examples (for insmod, use 'setup_strings' instead of 'in2000'):
                    171:  * -  in2000=ioport:0x220,noreset
                    172:  * -  in2000=period:250,disconnect:2,nosync:0x03
                    173:  * -  in2000=debug:0x1e
                    174:  * -  in2000=proc:3
                    175:  */
                    176: 
                    177: /* Normally, no defaults are specified... */
                    178: static char *setup_args[] =
                    179:       {"","","","","","","","",""};
                    180: 
                    181: /* filled in by 'insmod' */
                    182: static char *setup_strings = 0;
                    183: 
                    184: #ifdef MODULE_PARM
                    185: MODULE_PARM(setup_strings, "s");
                    186: #endif
                    187: 
                    188: 
                    189: static struct Scsi_Host *instance_list = 0;
                    190: 
                    191: 
                    192: 
                    193: static inline uchar read_3393(struct IN2000_hostdata *hostdata, uchar reg_num)
                    194: {
                    195:    write1_io(reg_num,IO_WD_ADDR);
                    196:    return read1_io(IO_WD_DATA);
                    197: }
                    198: 
                    199: 
                    200: #define READ_AUX_STAT() read1_io(IO_WD_ASR)
                    201: 
                    202: 
                    203: static inline void write_3393(struct IN2000_hostdata *hostdata, uchar reg_num, uchar value)
                    204: {
                    205:    write1_io(reg_num,IO_WD_ADDR);
                    206:    write1_io(value,IO_WD_DATA);
                    207: }
                    208: 
                    209: 
                    210: static inline void write_3393_cmd(struct IN2000_hostdata *hostdata, uchar cmd)
                    211: {
                    212: /*   while (READ_AUX_STAT() & ASR_CIP)
                    213:       printk("|");*/
                    214:    write1_io(WD_COMMAND,IO_WD_ADDR);
                    215:    write1_io(cmd,IO_WD_DATA);
                    216: }
                    217: 
                    218: 
                    219: static uchar read_1_byte(struct IN2000_hostdata *hostdata)
                    220: {
                    221: uchar asr, x = 0;
                    222: 
                    223:    write_3393(hostdata,WD_CONTROL, CTRL_IDI | CTRL_EDI | CTRL_POLLED);
                    224:    write_3393_cmd(hostdata,WD_CMD_TRANS_INFO|0x80);
                    225:    do {
                    226:       asr = READ_AUX_STAT();
                    227:       if (asr & ASR_DBR)
                    228:          x = read_3393(hostdata,WD_DATA);
                    229:       } while (!(asr & ASR_INT));
                    230:    return x;
                    231: }
                    232: 
                    233: 
                    234: static void write_3393_count(struct IN2000_hostdata *hostdata, unsigned long value)
                    235: {
                    236:    write1_io(WD_TRANSFER_COUNT_MSB,IO_WD_ADDR);
                    237:    write1_io((value >> 16),IO_WD_DATA);
                    238:    write1_io((value >> 8),IO_WD_DATA);
                    239:    write1_io(value,IO_WD_DATA);
                    240: }
                    241: 
                    242: 
                    243: static unsigned long read_3393_count(struct IN2000_hostdata *hostdata)
                    244: {
                    245: unsigned long value;
                    246: 
                    247:    write1_io(WD_TRANSFER_COUNT_MSB,IO_WD_ADDR);
                    248:    value = read1_io(IO_WD_DATA) << 16;
                    249:    value |= read1_io(IO_WD_DATA) << 8;
                    250:    value |= read1_io(IO_WD_DATA);
                    251:    return value;
                    252: }
                    253: 
                    254: 
                    255: /* The 33c93 needs to be told which direction a command transfers its
                    256:  * data; we use this function to figure it out. Returns true if there
                    257:  * will be a DATA_OUT phase with this command, false otherwise.
                    258:  * (Thanks to Joerg Dorchain for the research and suggestion.)
                    259:  */
                    260: static int is_dir_out(Scsi_Cmnd *cmd)
                    261: {
                    262:    switch (cmd->cmnd[0]) {
                    263:       case WRITE_6:           case WRITE_10:          case WRITE_12:
                    264:       case WRITE_LONG:        case WRITE_SAME:        case WRITE_BUFFER:
                    265:       case WRITE_VERIFY:      case WRITE_VERIFY_12:      
                    266:       case COMPARE:           case COPY:              case COPY_VERIFY:
                    267:       case SEARCH_EQUAL:      case SEARCH_HIGH:       case SEARCH_LOW:
                    268:       case SEARCH_EQUAL_12:   case SEARCH_HIGH_12:    case SEARCH_LOW_12:      
                    269:       case FORMAT_UNIT:       case REASSIGN_BLOCKS:   case RESERVE:
                    270:       case MODE_SELECT:       case MODE_SELECT_10:    case LOG_SELECT:
                    271:       case SEND_DIAGNOSTIC:   case CHANGE_DEFINITION: case UPDATE_BLOCK:
                    272:       case SET_WINDOW:        case MEDIUM_SCAN:       case SEND_VOLUME_TAG:
                    273:       case 0xea:
                    274:          return 1;
                    275:       default:
                    276:          return 0;
                    277:       }
                    278: }
                    279: 
                    280: 
                    281: 
                    282: static struct sx_period sx_table[] = {
                    283:    {  1, 0x20},
                    284:    {252, 0x20},
                    285:    {376, 0x30},
                    286:    {500, 0x40},
                    287:    {624, 0x50},
                    288:    {752, 0x60},
                    289:    {876, 0x70},
                    290:    {1000,0x00},
                    291:    {0,   0} };
                    292: 
                    293: static int round_period(unsigned int period)
                    294: {
                    295: int x;
                    296: 
                    297:    for (x=1; sx_table[x].period_ns; x++) {
                    298:       if ((period <= sx_table[x-0].period_ns) &&
                    299:           (period >  sx_table[x-1].period_ns)) {
                    300:          return x;
                    301:          }
                    302:       }
                    303:    return 7;
                    304: }
                    305: 
                    306: static uchar calc_sync_xfer(unsigned int period, unsigned int offset)
                    307: {
                    308: uchar result;
                    309: 
                    310:    period *= 4;   /* convert SDTR code to ns */
                    311:    result = sx_table[round_period(period)].reg_value;
                    312:    result |= (offset < OPTIMUM_SX_OFF)?offset:OPTIMUM_SX_OFF;
                    313:    return result;
                    314: }
                    315: 
                    316: 
                    317: 
                    318: static void in2000_execute(struct Scsi_Host *instance);
                    319: 
                    320: int in2000_queuecommand (Scsi_Cmnd *cmd, void (*done)(Scsi_Cmnd *))
                    321: {
                    322: struct IN2000_hostdata *hostdata;
                    323: Scsi_Cmnd *tmp;
                    324: unsigned long flags;
                    325: 
                    326:    hostdata = (struct IN2000_hostdata *)cmd->host->hostdata;
                    327: 
                    328: DB(DB_QUEUE_COMMAND,printk("Q-%d-%02x-%ld(",cmd->target,cmd->cmnd[0],cmd->pid))
                    329: 
                    330: /* Set up a few fields in the Scsi_Cmnd structure for our own use:
                    331:  *  - host_scribble is the pointer to the next cmd in the input queue
                    332:  *  - scsi_done points to the routine we call when a cmd is finished
                    333:  *  - result is what you'd expect
                    334:  */
                    335: 
                    336:    cmd->host_scribble = NULL;
                    337:    cmd->scsi_done = done;
                    338:    cmd->result = 0;
                    339: 
                    340: /* We use the Scsi_Pointer structure that's included with each command
                    341:  * as a scratchpad (as it's intended to be used!). The handy thing about
                    342:  * the SCp.xxx fields is that they're always associated with a given
                    343:  * cmd, and are preserved across disconnect-reselect. This means we
                    344:  * can pretty much ignore SAVE_POINTERS and RESTORE_POINTERS messages
                    345:  * if we keep all the critical pointers and counters in SCp:
                    346:  *  - SCp.ptr is the pointer into the RAM buffer
                    347:  *  - SCp.this_residual is the size of that buffer
                    348:  *  - SCp.buffer points to the current scatter-gather buffer
                    349:  *  - SCp.buffers_residual tells us how many S.G. buffers there are
                    350:  *  - SCp.have_data_in helps keep track of >2048 byte transfers
                    351:  *  - SCp.sent_command is not used
                    352:  *  - SCp.phase records this command's SRCID_ER bit setting
                    353:  */
                    354: 
                    355:    if (cmd->use_sg) {
                    356:       cmd->SCp.buffer = (struct scatterlist *)cmd->buffer;
                    357:       cmd->SCp.buffers_residual = cmd->use_sg - 1;
                    358:       cmd->SCp.ptr = (char *)cmd->SCp.buffer->address;
                    359:       cmd->SCp.this_residual = cmd->SCp.buffer->length;
                    360:       }
                    361:    else {
                    362:       cmd->SCp.buffer = NULL;
                    363:       cmd->SCp.buffers_residual = 0;
                    364:       cmd->SCp.ptr = (char *)cmd->request_buffer;
                    365:       cmd->SCp.this_residual = cmd->request_bufflen;
                    366:       }
                    367:    cmd->SCp.have_data_in = 0;
                    368: 
                    369: /* We don't set SCp.phase here - that's done in in2000_execute() */
                    370: 
                    371: /* WD docs state that at the conclusion of a "LEVEL2" command, the
                    372:  * status byte can be retrieved from the LUN register. Apparently,
                    373:  * this is the case only for *uninterrupted* LEVEL2 commands! If
                    374:  * there are any unexpected phases entered, even if they are 100%
                    375:  * legal (different devices may choose to do things differently),
                    376:  * the LEVEL2 command sequence is exited. This often occurs prior
                    377:  * to receiving the status byte, in which case the driver does a
                    378:  * status phase interrupt and gets the status byte on its own.
                    379:  * While such a command can then be "resumed" (ie restarted to
                    380:  * finish up as a LEVEL2 command), the LUN register will NOT be
                    381:  * a valid status byte at the command's conclusion, and we must
                    382:  * use the byte obtained during the earlier interrupt. Here, we
                    383:  * preset SCp.Status to an illegal value (0xff) so that when
                    384:  * this command finally completes, we can tell where the actual
                    385:  * status byte is stored.
                    386:  */
                    387: 
                    388:    cmd->SCp.Status = ILLEGAL_STATUS_BYTE;
                    389: 
                    390: /* We need to disable interrupts before messing with the input
                    391:  * queue and calling in2000_execute().
                    392:  */
                    393: 
                    394:    save_flags(flags);
                    395:    cli();
                    396: 
                    397:    /*
                    398:     * Add the cmd to the end of 'input_Q'. Note that REQUEST_SENSE
                    399:     * commands are added to the head of the queue so that the desired
                    400:     * sense data is not lost before REQUEST_SENSE executes.
                    401:     */
                    402: 
                    403:    if (!(hostdata->input_Q) || (cmd->cmnd[0] == REQUEST_SENSE)) {
                    404:       cmd->host_scribble = (uchar *)hostdata->input_Q;
                    405:       hostdata->input_Q = cmd;
                    406:       }
                    407:    else {   /* find the end of the queue */
                    408:       for (tmp=(Scsi_Cmnd *)hostdata->input_Q; tmp->host_scribble;
                    409:             tmp=(Scsi_Cmnd *)tmp->host_scribble)
                    410:          ;
                    411:       tmp->host_scribble = (uchar *)cmd;
                    412:       }
                    413: 
                    414: /* We know that there's at least one command in 'input_Q' now.
                    415:  * Go see if any of them are runnable!
                    416:  */
                    417: 
                    418:    in2000_execute(cmd->host);
                    419: 
                    420: DB(DB_QUEUE_COMMAND,printk(")Q-%ld ",cmd->pid))
                    421: 
                    422:    restore_flags(flags);
                    423:    return 0;
                    424: }
                    425: 
                    426: 
                    427: 
                    428: /*
                    429:  * This routine attempts to start a scsi command. If the host_card is
                    430:  * already connected, we give up immediately. Otherwise, look through
                    431:  * the input_Q, using the first command we find that's intended
                    432:  * for a currently non-busy target/lun.
                    433:  * Note that this function is always called with interrupts already
                    434:  * disabled (either from in2000_queuecommand() or in2000_intr()).
                    435:  */
                    436: static void in2000_execute (struct Scsi_Host *instance)
                    437: {
                    438: struct IN2000_hostdata *hostdata;
                    439: Scsi_Cmnd *cmd, *prev;
                    440: int i;
                    441: unsigned short *sp;
                    442: unsigned short f;
                    443: unsigned short flushbuf[16];
                    444: 
                    445: 
                    446:    hostdata = (struct IN2000_hostdata *)instance->hostdata;
                    447: 
                    448: DB(DB_EXECUTE,printk("EX("))
                    449: 
                    450:    if (hostdata->selecting || hostdata->connected) {
                    451: 
                    452: DB(DB_EXECUTE,printk(")EX-0 "))
                    453: 
                    454:       return;
                    455:       }
                    456: 
                    457:     /*
                    458:      * Search through the input_Q for a command destined
                    459:      * for an idle target/lun.
                    460:      */
                    461: 
                    462:    cmd = (Scsi_Cmnd *)hostdata->input_Q;
                    463:    prev = 0;
                    464:    while (cmd) {
                    465:       if (!(hostdata->busy[cmd->target] & (1 << cmd->lun)))
                    466:          break;
                    467:       prev = cmd;
                    468:       cmd = (Scsi_Cmnd *)cmd->host_scribble;
                    469:       }
                    470: 
                    471:    /* quit if queue empty or all possible targets are busy */
                    472: 
                    473:    if (!cmd) {
                    474: 
                    475: DB(DB_EXECUTE,printk(")EX-1 "))
                    476: 
                    477:       return;
                    478:       }
                    479: 
                    480:    /*  remove command from queue */
                    481:    
                    482:    if (prev)
                    483:       prev->host_scribble = cmd->host_scribble;
                    484:    else
                    485:       hostdata->input_Q = (Scsi_Cmnd *)cmd->host_scribble;
                    486: 
                    487: #ifdef PROC_STATISTICS
                    488:    hostdata->cmd_cnt[cmd->target]++;
                    489: #endif
                    490: 
                    491: /*
                    492:  * Start the selection process
                    493:  */
                    494: 
                    495:    if (is_dir_out(cmd))
                    496:       write_3393(hostdata,WD_DESTINATION_ID, cmd->target);
                    497:    else
                    498:       write_3393(hostdata,WD_DESTINATION_ID, cmd->target | DSTID_DPD);
                    499: 
                    500: /* Now we need to figure out whether or not this command is a good
                    501:  * candidate for disconnect/reselect. We guess to the best of our
                    502:  * ability, based on a set of hierarchical rules. When several
                    503:  * devices are operating simultaneously, disconnects are usually
                    504:  * an advantage. In a single device system, or if only 1 device
                    505:  * is being accessed, transfers usually go faster if disconnects
                    506:  * are not allowed:
                    507:  *
                    508:  * + Commands should NEVER disconnect if hostdata->disconnect =
                    509:  *   DIS_NEVER (this holds for tape drives also), and ALWAYS
                    510:  *   disconnect if hostdata->disconnect = DIS_ALWAYS.
                    511:  * + Tape drive commands should always be allowed to disconnect.
                    512:  * + Disconnect should be allowed if disconnected_Q isn't empty.
                    513:  * + Commands should NOT disconnect if input_Q is empty.
                    514:  * + Disconnect should be allowed if there are commands in input_Q
                    515:  *   for a different target/lun. In this case, the other commands
                    516:  *   should be made disconnect-able, if not already.
                    517:  *
                    518:  * I know, I know - this code would flunk me out of any
                    519:  * "C Programming 101" class ever offered. But it's easy
                    520:  * to change around and experiment with for now.
                    521:  */
                    522: 
                    523:    cmd->SCp.phase = 0;  /* assume no disconnect */
                    524:    if (hostdata->disconnect == DIS_NEVER)
                    525:       goto no;
                    526:    if (hostdata->disconnect == DIS_ALWAYS)
                    527:       goto yes;
                    528:    if (cmd->device->type == 1)   /* tape drive? */
                    529:       goto yes;
                    530:    if (hostdata->disconnected_Q) /* other commands disconnected? */
                    531:       goto yes;
                    532:    if (!(hostdata->input_Q))     /* input_Q empty? */
                    533:       goto no;
                    534:    for (prev=(Scsi_Cmnd *)hostdata->input_Q; prev;
                    535:          prev=(Scsi_Cmnd *)prev->host_scribble) {
                    536:       if ((prev->target != cmd->target) || (prev->lun != cmd->lun)) {
                    537:          for (prev=(Scsi_Cmnd *)hostdata->input_Q; prev;
                    538:                prev=(Scsi_Cmnd *)prev->host_scribble)
                    539:             prev->SCp.phase = 1;
                    540:          goto yes;
                    541:          }
                    542:       }
                    543:    goto no;
                    544: 
                    545: yes:
                    546:    cmd->SCp.phase = 1;
                    547: 
                    548: #ifdef PROC_STATISTICS
                    549:    hostdata->disc_allowed_cnt[cmd->target]++;
                    550: #endif
                    551: 
                    552: no:
                    553:    write_3393(hostdata,WD_SOURCE_ID,((cmd->SCp.phase)?SRCID_ER:0));
                    554: 
                    555:    write_3393(hostdata,WD_TARGET_LUN, cmd->lun);
                    556:    write_3393(hostdata,WD_SYNCHRONOUS_TRANSFER,hostdata->sync_xfer[cmd->target]);
                    557:    hostdata->busy[cmd->target] |= (1 << cmd->lun);
                    558: 
                    559:    if ((hostdata->level2 <= L2_NONE) ||
                    560:        (hostdata->sync_stat[cmd->target] == SS_UNSET)) {
                    561: 
                    562:          /*
                    563:           * Do a 'Select-With-ATN' command. This will end with
                    564:           * one of the following interrupts:
                    565:           *    CSR_RESEL_AM:  failure - can try again later.
                    566:           *    CSR_TIMEOUT:   failure - give up.
                    567:           *    CSR_SELECT:    success - proceed.
                    568:           */
                    569: 
                    570:       hostdata->selecting = cmd;
                    571: 
                    572: /* Every target has its own synchronous transfer setting, kept in
                    573:  * the sync_xfer array, and a corresponding status byte in sync_stat[].
                    574:  * Each target's sync_stat[] entry is initialized to SS_UNSET, and its
                    575:  * sync_xfer[] entry is initialized to the default/safe value. SS_UNSET
                    576:  * means that the parameters are undetermined as yet, and that we
                    577:  * need to send an SDTR message to this device after selection is
                    578:  * complete. We set SS_FIRST to tell the interrupt routine to do so,
                    579:  * unless we don't want to even _try_ synchronous transfers: In this
                    580:  * case we set SS_SET to make the defaults final.
                    581:  */
                    582:       if (hostdata->sync_stat[cmd->target] == SS_UNSET) {
                    583:          if (hostdata->sync_off & (1 << cmd->target))
                    584:             hostdata->sync_stat[cmd->target] = SS_SET;
                    585:          else
                    586:             hostdata->sync_stat[cmd->target] = SS_FIRST;
                    587:          }
                    588:       hostdata->state = S_SELECTING;
                    589:       write_3393_count(hostdata,0); /* this guarantees a DATA_PHASE interrupt */
                    590:       write_3393_cmd(hostdata,WD_CMD_SEL_ATN);
                    591:       }
                    592: 
                    593:    else {
                    594: 
                    595:          /*
                    596:           * Do a 'Select-With-ATN-Xfer' command. This will end with
                    597:           * one of the following interrupts:
                    598:           *    CSR_RESEL_AM:  failure - can try again later.
                    599:           *    CSR_TIMEOUT:   failure - give up.
                    600:           *    anything else: success - proceed.
                    601:           */
                    602: 
                    603:       hostdata->connected = cmd;
                    604:       write_3393(hostdata,WD_COMMAND_PHASE, 0);
                    605: 
                    606:    /* copy command_descriptor_block into WD chip
                    607:     * (take advantage of auto-incrementing)
                    608:     */
                    609: 
                    610:       write1_io(WD_CDB_1, IO_WD_ADDR);
                    611:       for (i=0; i<cmd->cmd_len; i++)
                    612:          write1_io(cmd->cmnd[i], IO_WD_DATA);
                    613: 
                    614:    /* The wd33c93 only knows about Group 0, 1, and 5 commands when
                    615:     * it's doing a 'select-and-transfer'. To be safe, we write the
                    616:     * size of the CDB into the OWN_ID register for every case. This
                    617:     * way there won't be problems with vendor-unique, audio, etc.
                    618:     */
                    619: 
                    620:       write_3393(hostdata, WD_OWN_ID, cmd->cmd_len);
                    621: 
                    622:    /* When doing a non-disconnect command, we can save ourselves a DATA
                    623:     * phase interrupt later by setting everything up now. With writes we
                    624:     * need to pre-fill the fifo; if there's room for the 32 flush bytes,
                    625:     * put them in there too - that'll avoid a fifo interrupt. Reads are
                    626:     * somewhat simpler.
                    627:     * KLUDGE NOTE: It seems that you can't completely fill the fifo here:
                    628:     * This results in the IO_FIFO_COUNT register rolling over to zero,
                    629:     * and apparently the gate array logic sees this as empty, not full,
                    630:     * so the 3393 chip is never signalled to start reading from the
                    631:     * fifo. Or maybe it's seen as a permanent fifo interrupt condition.
                    632:     * Regardless, we fix this by temporarily pretending that the fifo
                    633:     * is 16 bytes smaller. (I see now that the old driver has a comment
                    634:     * about "don't fill completely" in an analogous place - must be the
                    635:     * same deal.) This results in CDROM, swap partitions, and tape drives
                    636:     * needing an extra interrupt per write command - I think we can live
                    637:     * with that!
                    638:     */
                    639: 
                    640:       if (!(cmd->SCp.phase)) {
                    641:          write_3393_count(hostdata, cmd->SCp.this_residual);
                    642:          write_3393(hostdata,WD_CONTROL, CTRL_IDI | CTRL_EDI | CTRL_BUS);
                    643:          write1_io(0, IO_FIFO_WRITE);  /* clear fifo counter, write mode */
                    644: 
                    645:          if (is_dir_out(cmd)) {
                    646:             hostdata->fifo = FI_FIFO_WRITING;
                    647:             if ((i = cmd->SCp.this_residual) > (IN2000_FIFO_SIZE - 16) )
                    648:                i = IN2000_FIFO_SIZE - 16;
                    649:             cmd->SCp.have_data_in = i;    /* this much data in fifo */
                    650:             i >>= 1;                      /* Gulp. Assuming modulo 2. */
                    651:             sp = (unsigned short *)cmd->SCp.ptr;
                    652:             f = hostdata->io_base + IO_FIFO;
                    653: 
                    654: #ifdef FAST_WRITE_IO
                    655: 
                    656:             FAST_WRITE2_IO();
                    657: #else
                    658:             while (i--)
                    659:                write2_io(*sp++,IO_FIFO);
                    660: 
                    661: #endif
                    662: 
                    663:       /* Is there room for the flush bytes? */
                    664: 
                    665:             if (cmd->SCp.have_data_in <= ((IN2000_FIFO_SIZE - 16) - 32)) {
                    666:                sp = flushbuf;
                    667:                i = 16;
                    668: 
                    669: #ifdef FAST_WRITE_IO
                    670: 
                    671:                FAST_WRITE2_IO();
                    672: #else
                    673:                while (i--)
                    674:                   write2_io(0,IO_FIFO);
                    675: 
                    676: #endif
                    677: 
                    678:                }
                    679:             }
                    680: 
                    681:          else {
                    682:             write1_io(0, IO_FIFO_READ);   /* put fifo in read mode */
                    683:             hostdata->fifo = FI_FIFO_READING;
                    684:             cmd->SCp.have_data_in = 0;    /* nothing transfered yet */
                    685:             }
                    686: 
                    687:          }
                    688:       else {
                    689:          write_3393_count(hostdata,0); /* this guarantees a DATA_PHASE interrupt */
                    690:          }
                    691:       hostdata->state = S_RUNNING_LEVEL2;
                    692:       write_3393_cmd(hostdata,WD_CMD_SEL_ATN_XFER);
                    693:       }
                    694: 
                    695:    /*
                    696:     * Since the SCSI bus can handle only 1 connection at a time,
                    697:     * we get out of here now. If the selection fails, or when
                    698:     * the command disconnects, we'll come back to this routine
                    699:     * to search the input_Q again...
                    700:     */
                    701:       
                    702: DB(DB_EXECUTE,printk("%s%ld)EX-2 ",(cmd->SCp.phase)?"d:":"",cmd->pid))
                    703: 
                    704: }
                    705: 
                    706: 
                    707: 
                    708: static void transfer_pio(uchar *buf, int cnt,
                    709:                   int data_in_dir, struct IN2000_hostdata *hostdata)
                    710: {
                    711: uchar asr;
                    712: 
                    713: DB(DB_TRANSFER,printk("(%p,%d,%s)",buf,cnt,data_in_dir?"in":"out"))
                    714: 
                    715:    write_3393(hostdata,WD_CONTROL, CTRL_IDI | CTRL_EDI | CTRL_POLLED);
                    716:    write_3393_count(hostdata,cnt);
                    717:    write_3393_cmd(hostdata,WD_CMD_TRANS_INFO);
                    718:    if (data_in_dir) {
                    719:       do {
                    720:          asr = READ_AUX_STAT();
                    721:          if (asr & ASR_DBR)
                    722:             *buf++ = read_3393(hostdata,WD_DATA);
                    723:          } while (!(asr & ASR_INT));
                    724:       }
                    725:    else {
                    726:       do {
                    727:          asr = READ_AUX_STAT();
                    728:          if (asr & ASR_DBR)
                    729:             write_3393(hostdata,WD_DATA, *buf++);
                    730:          } while (!(asr & ASR_INT));
                    731:       }
                    732: 
                    733:    /* Note: we are returning with the interrupt UN-cleared.
                    734:    * Since (presumably) an entire I/O operation has
                    735:    * completed, the bus phase is probably different, and
                    736:    * the interrupt routine will discover this when it
                    737:    * responds to the uncleared int.
                    738:    */
                    739: 
                    740: }
                    741: 
                    742: 
                    743: 
                    744: static void transfer_bytes(Scsi_Cmnd *cmd, int data_in_dir)
                    745: {
                    746: struct IN2000_hostdata *hostdata;
                    747: unsigned short *sp;
                    748: unsigned short f;
                    749: int i;
                    750: 
                    751:    hostdata = (struct IN2000_hostdata *)cmd->host->hostdata;
                    752: 
                    753: /* Normally, you'd expect 'this_residual' to be non-zero here.
                    754:  * In a series of scatter-gather transfers, however, this
                    755:  * routine will usually be called with 'this_residual' equal
                    756:  * to 0 and 'buffers_residual' non-zero. This means that a
                    757:  * previous transfer completed, clearing 'this_residual', and
                    758:  * now we need to setup the next scatter-gather buffer as the
                    759:  * source or destination for THIS transfer.
                    760:  */
                    761:    if (!cmd->SCp.this_residual && cmd->SCp.buffers_residual) {
                    762:       ++cmd->SCp.buffer;
                    763:       --cmd->SCp.buffers_residual;
                    764:       cmd->SCp.this_residual = cmd->SCp.buffer->length;
                    765:       cmd->SCp.ptr = cmd->SCp.buffer->address;
                    766:       }
                    767: 
                    768: /* Set up hardware registers */
                    769: 
                    770:    write_3393(hostdata,WD_SYNCHRONOUS_TRANSFER,hostdata->sync_xfer[cmd->target]);
                    771:    write_3393_count(hostdata,cmd->SCp.this_residual);
                    772:    write_3393(hostdata,WD_CONTROL, CTRL_IDI | CTRL_EDI | CTRL_BUS);
                    773:    write1_io(0,IO_FIFO_WRITE); /* zero counter, assume write */
                    774: 
                    775: /* Reading is easy. Just issue the command and return - we'll
                    776:  * get an interrupt later when we have actual data to worry about.
                    777:  */
                    778: 
                    779:    if (data_in_dir) {
                    780:       write1_io(0,IO_FIFO_READ);
                    781:       if ((hostdata->level2 >= L2_DATA) ||
                    782:           (hostdata->level2 == L2_BASIC && cmd->SCp.phase == 0)) {
                    783:          write_3393(hostdata,WD_COMMAND_PHASE,0x45);
                    784:          write_3393_cmd(hostdata,WD_CMD_SEL_ATN_XFER);
                    785:          hostdata->state = S_RUNNING_LEVEL2;
                    786:          }
                    787:       else
                    788:          write_3393_cmd(hostdata,WD_CMD_TRANS_INFO);
                    789:       hostdata->fifo = FI_FIFO_READING;
                    790:       cmd->SCp.have_data_in = 0;
                    791:       return;
                    792:       }
                    793: 
                    794: /* Writing is more involved - we'll start the WD chip and write as
                    795:  * much data to the fifo as we can right now. Later interrupts will
                    796:  * write any bytes that don't make it at this stage.
                    797:  */
                    798: 
                    799:       if ((hostdata->level2 >= L2_DATA) ||
                    800:           (hostdata->level2 == L2_BASIC && cmd->SCp.phase == 0)) {
                    801:       write_3393(hostdata,WD_COMMAND_PHASE,0x45);
                    802:       write_3393_cmd(hostdata,WD_CMD_SEL_ATN_XFER);
                    803:       hostdata->state = S_RUNNING_LEVEL2;
                    804:       }
                    805:    else
                    806:       write_3393_cmd(hostdata,WD_CMD_TRANS_INFO);
                    807:    hostdata->fifo = FI_FIFO_WRITING;
                    808:    sp = (unsigned short *)cmd->SCp.ptr;
                    809: 
                    810:    if ((i = cmd->SCp.this_residual) > IN2000_FIFO_SIZE)
                    811:       i = IN2000_FIFO_SIZE;
                    812:    cmd->SCp.have_data_in = i;
                    813:    i >>= 1;    /* Gulp. We assume this_residual is modulo 2 */
                    814:    f = hostdata->io_base + IO_FIFO;
                    815: 
                    816: #ifdef FAST_WRITE_IO
                    817: 
                    818:    FAST_WRITE2_IO();
                    819: #else
                    820:    while (i--)
                    821:       write2_io(*sp++,IO_FIFO);
                    822: 
                    823: #endif
                    824: 
                    825: }
                    826: 
                    827: 
                    828: /* We need to use spin_lock_irqsave() & spin_unlock_irqrestore() in this
                    829:  * function in order to work in an SMP environment. (I'd be surprised
                    830:  * if the driver is ever used by anyone on a real multi-CPU motherboard,
                    831:  * but it _does_ need to be able to compile and run in an SMP kernel.)
                    832:  */
                    833: 
                    834: static void in2000_intr (int irqnum, void * dev_id, struct pt_regs *ptregs)
                    835: {
                    836: struct Scsi_Host *instance;
                    837: struct IN2000_hostdata *hostdata;
                    838: Scsi_Cmnd *patch, *cmd;
                    839: uchar asr, sr, phs, id, lun, *ucp, msg;
                    840: int i,j;
                    841: unsigned long length;
                    842: unsigned short *sp;
                    843: unsigned short f;
                    844: unsigned long flags;
                    845: 
                    846:    for (instance = instance_list; instance; instance = instance->next) {
                    847:       if (instance->irq == irqnum)
                    848:          break;
                    849:       }
                    850:    if (!instance) {
                    851:       printk("*** Hmm... interrupts are screwed up! ***\n");
                    852:       return;
                    853:       }
                    854:    hostdata = (struct IN2000_hostdata *)instance->hostdata;
                    855: 
                    856: /* Get the spin_lock and disable further ints, for SMP */
                    857: 
                    858:    CLISPIN_LOCK(flags);
                    859: 
                    860: #ifdef PROC_STATISTICS
                    861:    hostdata->int_cnt++;
                    862: #endif
                    863: 
                    864: /* The IN2000 card has 2 interrupt sources OR'ed onto its IRQ line - the
                    865:  * WD3393 chip and the 2k fifo (which is actually a dual-port RAM combined
                    866:  * with a big logic array, so it's a little different than what you might
                    867:  * expect). As far as I know, there's no reason that BOTH can't be active
                    868:  * at the same time, but there's a problem: while we can read the 3393
                    869:  * to tell if _it_ wants an interrupt, I don't know of a way to ask the
                    870:  * fifo the same question. The best we can do is check the 3393 and if
                    871:  * it _isn't_ the source of the interrupt, then we can be pretty sure
                    872:  * that the fifo is the culprit.
                    873:  *  UPDATE: I have it on good authority (Bill Earnest) that bit 0 of the
                    874:  *          IO_FIFO_COUNT register mirrors the fifo interrupt state. I
                    875:  *          assume that bit clear means interrupt active. As it turns
                    876:  *          out, the driver really doesn't need to check for this after
                    877:  *          all, so my remarks above about a 'problem' can safely be
                    878:  *          ignored. The way the logic is set up, there's no advantage
                    879:  *          (that I can see) to worrying about it.
                    880:  *
                    881:  * It seems that the fifo interrupt signal is negated when we extract
                    882:  * bytes during read or write bytes during write.
                    883:  *  - fifo will interrupt when data is moving from it to the 3393, and
                    884:  *    there are 31 (or less?) bytes left to go. This is sort of short-
                    885:  *    sighted: what if you don't WANT to do more? In any case, our
                    886:  *    response is to push more into the fifo - either actual data or
                    887:  *    dummy bytes if need be. Note that we apparently have to write at
                    888:  *    least 32 additional bytes to the fifo after an interrupt in order
                    889:  *    to get it to release the ones it was holding on to - writing fewer
                    890:  *    than 32 will result in another fifo int.
                    891:  *  UPDATE: Again, info from Bill Earnest makes this more understandable:
                    892:  *          32 bytes = two counts of the fifo counter register. He tells
                    893:  *          me that the fifo interrupt is a non-latching signal derived
                    894:  *          from a straightforward boolean interpretation of the 7
                    895:  *          highest bits of the fifo counter and the fifo-read/fifo-write
                    896:  *          state. Who'd a thought?
                    897:  */
                    898: 
                    899:    write1_io(0, IO_LED_ON);
                    900:    asr = READ_AUX_STAT();
                    901:    if (!(asr & ASR_INT)) {    /* no WD33c93 interrupt? */
                    902: 
                    903: /* Ok. This is definitely a FIFO-only interrupt.
                    904:  *
                    905:  * If FI_FIFO_READING is set, there are up to 2048 bytes waiting to be read,
                    906:  * maybe more to come from the SCSI bus. Read as many as we can out of the
                    907:  * fifo and into memory at the location of SCp.ptr[SCp.have_data_in], and
                    908:  * update have_data_in afterwards.
                    909:  *
                    910:  * If we have FI_FIFO_WRITING, the FIFO has almost run out of bytes to move
                    911:  * into the WD3393 chip (I think the interrupt happens when there are 31
                    912:  * bytes left, but it may be fewer...). The 3393 is still waiting, so we
                    913:  * shove some more into the fifo, which gets things moving again. If the
                    914:  * original SCSI command specified more than 2048 bytes, there may still
                    915:  * be some of that data left: fine - use it (from SCp.ptr[SCp.have_data_in]).
                    916:  * Don't forget to update have_data_in. If we've already written out the
                    917:  * entire buffer, feed 32 dummy bytes to the fifo - they're needed to
                    918:  * push out the remaining real data.
                    919:  *    (Big thanks to Bill Earnest for getting me out of the mud in here.)
                    920:  */
                    921: 
                    922:       cmd = (Scsi_Cmnd *)hostdata->connected;   /* assume we're connected */
                    923: CHECK_NULL(cmd,"fifo_int")
                    924: 
                    925:       if (hostdata->fifo == FI_FIFO_READING) {
                    926: 
                    927: DB(DB_FIFO,printk("{R:%02x} ",read1_io(IO_FIFO_COUNT)))
                    928: 
                    929:          sp = (unsigned short *)(cmd->SCp.ptr + cmd->SCp.have_data_in);
                    930:          i = read1_io(IO_FIFO_COUNT) & 0xfe;
                    931:          i <<= 2;    /* # of words waiting in the fifo */
                    932:          f = hostdata->io_base + IO_FIFO;
                    933: 
                    934: #ifdef FAST_READ_IO
                    935: 
                    936:          FAST_READ2_IO();
                    937: #else
                    938:          while (i--)
                    939:             *sp++ = read2_io(IO_FIFO);
                    940: 
                    941: #endif
                    942: 
                    943:          i = sp - (unsigned short *)(cmd->SCp.ptr + cmd->SCp.have_data_in);
                    944:          i <<= 1;
                    945:          cmd->SCp.have_data_in += i;
                    946:          }
                    947: 
                    948:       else if (hostdata->fifo == FI_FIFO_WRITING) {
                    949: 
                    950: DB(DB_FIFO,printk("{W:%02x} ",read1_io(IO_FIFO_COUNT)))
                    951: 
                    952: /* If all bytes have been written to the fifo, flush out the stragglers.
                    953:  * Note that while writing 16 dummy words seems arbitrary, we don't
                    954:  * have another choice that I can see. What we really want is to read
                    955:  * the 3393 transfer count register (that would tell us how many bytes
                    956:  * needed flushing), but the TRANSFER_INFO command hasn't completed
                    957:  * yet (not enough bytes!) and that register won't be accessible. So,
                    958:  * we use 16 words - a number obtained through trial and error.
                    959:  *  UPDATE: Bill says this is exactly what Always does, so there.
                    960:  *          More thanks due him for help in this section.
                    961:  */
                    962: 
                    963:          if (cmd->SCp.this_residual == cmd->SCp.have_data_in) {
                    964:             i = 16;
                    965:             while (i--)          /* write 32 dummy bytes */
                    966:                write2_io(0,IO_FIFO);
                    967:             }
                    968: 
                    969: /* If there are still bytes left in the SCSI buffer, write as many as we
                    970:  * can out to the fifo.
                    971:  */
                    972: 
                    973:          else {
                    974:             sp = (unsigned short *)(cmd->SCp.ptr + cmd->SCp.have_data_in);
                    975:             i = cmd->SCp.this_residual - cmd->SCp.have_data_in;   /* bytes yet to go */
                    976:             j = read1_io(IO_FIFO_COUNT) & 0xfe;
                    977:             j <<= 2;    /* how many words the fifo has room for */
                    978:             if ((j << 1) > i)
                    979:                j = (i >> 1);
                    980:             while (j--)
                    981:                write2_io(*sp++,IO_FIFO);
                    982: 
                    983:             i = sp - (unsigned short *)(cmd->SCp.ptr + cmd->SCp.have_data_in);
                    984:             i <<= 1;
                    985:             cmd->SCp.have_data_in += i;
                    986:             }
                    987:          }
                    988: 
                    989:       else {
                    990:             printk("*** Spurious FIFO interrupt ***");
                    991:             }
                    992: 
                    993:       write1_io(0, IO_LED_OFF);
                    994: 
                    995: /* release the SMP spin_lock and restore irq state */
                    996:       CLISPIN_UNLOCK(flags);
                    997:       return;
                    998:       }
                    999: 
                   1000: /* This interrupt was triggered by the WD33c93 chip. The fifo interrupt
                   1001:  * may also be asserted, but we don't bother to check it: we get more
                   1002:  * detailed info from FIFO_READING and FIFO_WRITING (see below).
                   1003:  */
                   1004: 
                   1005:    cmd = (Scsi_Cmnd *)hostdata->connected;   /* assume we're connected */
                   1006:    sr = read_3393(hostdata,WD_SCSI_STATUS);  /* clear the interrupt */
                   1007:    phs = read_3393(hostdata,WD_COMMAND_PHASE);
                   1008: 
                   1009:    if (!cmd && (sr != CSR_RESEL_AM && sr != CSR_TIMEOUT && sr != CSR_SELECT)) {
                   1010:       printk("\nNR:wd-intr-1\n");
                   1011:       write1_io(0, IO_LED_OFF);
                   1012: 
                   1013: /* release the SMP spin_lock and restore irq state */
                   1014:       CLISPIN_UNLOCK(flags);
                   1015:       return;
                   1016:       }
                   1017: 
                   1018: DB(DB_INTR,printk("{%02x:%02x-",asr,sr))
                   1019: 
                   1020: /* After starting a FIFO-based transfer, the next _WD3393_ interrupt is
                   1021:  * guaranteed to be in response to the completion of the transfer.
                   1022:  * If we were reading, there's probably data in the fifo that needs
                   1023:  * to be copied into RAM - do that here. Also, we have to update
                   1024:  * 'this_residual' and 'ptr' based on the contents of the
                   1025:  * TRANSFER_COUNT register, in case the device decided to do an
                   1026:  * intermediate disconnect (a device may do this if it has to
                   1027:  * do a seek,  or just to be nice and let other devices have
                   1028:  * some bus time during long transfers).
                   1029:  * After doing whatever is necessary with the fifo, we go on and
                   1030:  * service the WD3393 interrupt normally.
                   1031:  */
                   1032: 
                   1033:    if (hostdata->fifo == FI_FIFO_READING) {
                   1034: 
                   1035: /* buffer index = start-of-buffer + #-of-bytes-already-read */
                   1036: 
                   1037:       sp = (unsigned short *)(cmd->SCp.ptr + cmd->SCp.have_data_in);
                   1038: 
                   1039: /* bytes remaining in fifo = (total-wanted - #-not-got) - #-already-read */
                   1040: 
                   1041:       i = (cmd->SCp.this_residual - read_3393_count(hostdata)) - cmd->SCp.have_data_in;
                   1042:       i >>= 1;    /* Gulp. We assume this will always be modulo 2 */
                   1043:       f = hostdata->io_base + IO_FIFO;
                   1044: 
                   1045: #ifdef FAST_READ_IO
                   1046: 
                   1047:       FAST_READ2_IO();
                   1048: #else
                   1049:       while (i--)
                   1050:          *sp++ = read2_io(IO_FIFO);
                   1051: 
                   1052: #endif
                   1053: 
                   1054:       hostdata->fifo = FI_FIFO_UNUSED;
                   1055:       length = cmd->SCp.this_residual;
                   1056:       cmd->SCp.this_residual = read_3393_count(hostdata);
                   1057:       cmd->SCp.ptr += (length - cmd->SCp.this_residual);
                   1058: 
                   1059: DB(DB_TRANSFER,printk("(%p,%d)",cmd->SCp.ptr,cmd->SCp.this_residual))
                   1060: 
                   1061:       }
                   1062: 
                   1063:    else if (hostdata->fifo == FI_FIFO_WRITING) {
                   1064:       hostdata->fifo = FI_FIFO_UNUSED;
                   1065:       length = cmd->SCp.this_residual;
                   1066:       cmd->SCp.this_residual = read_3393_count(hostdata);
                   1067:       cmd->SCp.ptr += (length - cmd->SCp.this_residual);
                   1068: 
                   1069: DB(DB_TRANSFER,printk("(%p,%d)",cmd->SCp.ptr,cmd->SCp.this_residual))
                   1070: 
                   1071:       }
                   1072: 
                   1073: /* Respond to the specific WD3393 interrupt - there are quite a few! */
                   1074: 
                   1075:    switch (sr) {
                   1076: 
                   1077:       case CSR_TIMEOUT:
                   1078: DB(DB_INTR,printk("TIMEOUT"))
                   1079: 
                   1080:          if (hostdata->state == S_RUNNING_LEVEL2)
                   1081:             hostdata->connected = NULL;
                   1082:          else {
                   1083:             cmd = (Scsi_Cmnd *)hostdata->selecting;   /* get a valid cmd */
                   1084: CHECK_NULL(cmd,"csr_timeout")
                   1085:             hostdata->selecting = NULL;
                   1086:             }
                   1087: 
                   1088:          cmd->result = DID_NO_CONNECT << 16;
                   1089:          hostdata->busy[cmd->target] &= ~(1 << cmd->lun);
                   1090:          hostdata->state = S_UNCONNECTED;
                   1091:          cmd->scsi_done(cmd);
                   1092: 
                   1093: /* We are not connected to a target - check to see if there
                   1094:  * are commands waiting to be executed.
                   1095:  */
                   1096: 
                   1097:          in2000_execute(instance);
                   1098:          break;
                   1099: 
                   1100: 
                   1101: /* Note: this interrupt should not occur in a LEVEL2 command */
                   1102: 
                   1103:       case CSR_SELECT:
                   1104: DB(DB_INTR,printk("SELECT"))
                   1105:          hostdata->connected = cmd = (Scsi_Cmnd *)hostdata->selecting;
                   1106: CHECK_NULL(cmd,"csr_select")
                   1107:          hostdata->selecting = NULL;
                   1108: 
                   1109:       /* construct an IDENTIFY message with correct disconnect bit */
                   1110: 
                   1111:          hostdata->outgoing_msg[0] = (0x80 | 0x00 | cmd->lun);
                   1112:          if (cmd->SCp.phase)
                   1113:             hostdata->outgoing_msg[0] |= 0x40;
                   1114: 
                   1115:          if (hostdata->sync_stat[cmd->target] == SS_FIRST) {
                   1116: #ifdef SYNC_DEBUG
                   1117: printk(" sending SDTR ");
                   1118: #endif
                   1119: 
                   1120:             hostdata->sync_stat[cmd->target] = SS_WAITING;
                   1121: 
                   1122:       /* tack on a 2nd message to ask about synchronous transfers */
                   1123: 
                   1124:             hostdata->outgoing_msg[1] = EXTENDED_MESSAGE;
                   1125:             hostdata->outgoing_msg[2] = 3;
                   1126:             hostdata->outgoing_msg[3] = EXTENDED_SDTR;
                   1127:             hostdata->outgoing_msg[4] = OPTIMUM_SX_PER/4;
                   1128:             hostdata->outgoing_msg[5] = OPTIMUM_SX_OFF;
                   1129:             hostdata->outgoing_len = 6;
                   1130:             }
                   1131:          else
                   1132:             hostdata->outgoing_len = 1;
                   1133: 
                   1134:          hostdata->state = S_CONNECTED;
                   1135:          break;
                   1136: 
                   1137: 
                   1138:       case CSR_XFER_DONE|PHS_DATA_IN:
                   1139:       case CSR_UNEXP    |PHS_DATA_IN:
                   1140:       case CSR_SRV_REQ  |PHS_DATA_IN:
                   1141: DB(DB_INTR,printk("IN-%d.%d",cmd->SCp.this_residual,cmd->SCp.buffers_residual))
                   1142:          transfer_bytes(cmd, DATA_IN_DIR);
                   1143:          if (hostdata->state != S_RUNNING_LEVEL2)
                   1144:             hostdata->state = S_CONNECTED;
                   1145:          break;
                   1146: 
                   1147: 
                   1148:       case CSR_XFER_DONE|PHS_DATA_OUT:
                   1149:       case CSR_UNEXP    |PHS_DATA_OUT:
                   1150:       case CSR_SRV_REQ  |PHS_DATA_OUT:
                   1151: DB(DB_INTR,printk("OUT-%d.%d",cmd->SCp.this_residual,cmd->SCp.buffers_residual))
                   1152:          transfer_bytes(cmd, DATA_OUT_DIR);
                   1153:          if (hostdata->state != S_RUNNING_LEVEL2)
                   1154:             hostdata->state = S_CONNECTED;
                   1155:          break;
                   1156: 
                   1157: 
                   1158: /* Note: this interrupt should not occur in a LEVEL2 command */
                   1159: 
                   1160:       case CSR_XFER_DONE|PHS_COMMAND:
                   1161:       case CSR_UNEXP    |PHS_COMMAND:
                   1162:       case CSR_SRV_REQ  |PHS_COMMAND:
                   1163: DB(DB_INTR,printk("CMND-%02x,%ld",cmd->cmnd[0],cmd->pid))
                   1164:          transfer_pio(cmd->cmnd, cmd->cmd_len, DATA_OUT_DIR, hostdata);
                   1165:          hostdata->state = S_CONNECTED;
                   1166:          break;
                   1167: 
                   1168: 
                   1169:       case CSR_XFER_DONE|PHS_STATUS:
                   1170:       case CSR_UNEXP    |PHS_STATUS:
                   1171:       case CSR_SRV_REQ  |PHS_STATUS:
                   1172: DB(DB_INTR,printk("STATUS="))
                   1173: 
                   1174:          cmd->SCp.Status = read_1_byte(hostdata);
                   1175: DB(DB_INTR,printk("%02x",cmd->SCp.Status))
                   1176:          if (hostdata->level2 >= L2_BASIC) {
                   1177:             sr = read_3393(hostdata,WD_SCSI_STATUS);  /* clear interrupt */
                   1178:             hostdata->state = S_RUNNING_LEVEL2;
                   1179:             write_3393(hostdata,WD_COMMAND_PHASE, 0x50);
                   1180:             write_3393_cmd(hostdata,WD_CMD_SEL_ATN_XFER);
                   1181:             }
                   1182:          else {
                   1183:             hostdata->state = S_CONNECTED;
                   1184:             }
                   1185:          break;
                   1186: 
                   1187: 
                   1188:       case CSR_XFER_DONE|PHS_MESS_IN:
                   1189:       case CSR_UNEXP    |PHS_MESS_IN:
                   1190:       case CSR_SRV_REQ  |PHS_MESS_IN:
                   1191: DB(DB_INTR,printk("MSG_IN="))
                   1192: 
                   1193:          msg = read_1_byte(hostdata);
                   1194:          sr = read_3393(hostdata,WD_SCSI_STATUS);  /* clear interrupt */
                   1195: 
                   1196:          hostdata->incoming_msg[hostdata->incoming_ptr] = msg;
                   1197:          if (hostdata->incoming_msg[0] == EXTENDED_MESSAGE)
                   1198:             msg = EXTENDED_MESSAGE;
                   1199:          else
                   1200:             hostdata->incoming_ptr = 0;
                   1201: 
                   1202:          cmd->SCp.Message = msg;
                   1203:          switch (msg) {
                   1204: 
                   1205:             case COMMAND_COMPLETE:
                   1206: DB(DB_INTR,printk("CCMP-%ld",cmd->pid))
                   1207:                write_3393_cmd(hostdata,WD_CMD_NEGATE_ACK);
                   1208:                hostdata->state = S_PRE_CMP_DISC;
                   1209:                break;
                   1210: 
                   1211:             case SAVE_POINTERS:
                   1212: DB(DB_INTR,printk("SDP"))
                   1213:                write_3393_cmd(hostdata,WD_CMD_NEGATE_ACK);
                   1214:                hostdata->state = S_CONNECTED;
                   1215:                break;
                   1216: 
                   1217:             case RESTORE_POINTERS:
                   1218: DB(DB_INTR,printk("RDP"))
                   1219:                if (hostdata->level2 >= L2_BASIC) {
                   1220:                   write_3393(hostdata,WD_COMMAND_PHASE, 0x45);
                   1221:                   write_3393_cmd(hostdata,WD_CMD_SEL_ATN_XFER);
                   1222:                   hostdata->state = S_RUNNING_LEVEL2;
                   1223:                   }
                   1224:                else {
                   1225:                   write_3393_cmd(hostdata,WD_CMD_NEGATE_ACK);
                   1226:                   hostdata->state = S_CONNECTED;
                   1227:                   }
                   1228:                break;
                   1229: 
                   1230:             case DISCONNECT:
                   1231: DB(DB_INTR,printk("DIS"))
                   1232:                cmd->device->disconnect = 1;
                   1233:                write_3393_cmd(hostdata,WD_CMD_NEGATE_ACK);
                   1234:                hostdata->state = S_PRE_TMP_DISC;
                   1235:                break;
                   1236: 
                   1237:             case MESSAGE_REJECT:
                   1238: DB(DB_INTR,printk("REJ"))
                   1239: #ifdef SYNC_DEBUG
                   1240: printk("-REJ-");
                   1241: #endif
                   1242:                if (hostdata->sync_stat[cmd->target] == SS_WAITING)
                   1243:                   hostdata->sync_stat[cmd->target] = SS_SET;
                   1244:                write_3393_cmd(hostdata,WD_CMD_NEGATE_ACK);
                   1245:                hostdata->state = S_CONNECTED;
                   1246:                break;
                   1247: 
                   1248:             case EXTENDED_MESSAGE:
                   1249: DB(DB_INTR,printk("EXT"))
                   1250: 
                   1251:                ucp = hostdata->incoming_msg;
                   1252: 
                   1253: #ifdef SYNC_DEBUG
                   1254: printk("%02x",ucp[hostdata->incoming_ptr]);
                   1255: #endif
                   1256:          /* Is this the last byte of the extended message? */
                   1257: 
                   1258:                if ((hostdata->incoming_ptr >= 2) &&
                   1259:                    (hostdata->incoming_ptr == (ucp[1] + 1))) {
                   1260: 
                   1261:                   switch (ucp[2]) {   /* what's the EXTENDED code? */
                   1262:                      case EXTENDED_SDTR:
                   1263:                         id = calc_sync_xfer(ucp[3],ucp[4]);
                   1264:                         if (hostdata->sync_stat[cmd->target] != SS_WAITING) {
                   1265: 
                   1266: /* A device has sent an unsolicited SDTR message; rather than go
                   1267:  * through the effort of decoding it and then figuring out what
                   1268:  * our reply should be, we're just gonna say that we have a
                   1269:  * synchronous fifo depth of 0. This will result in asynchronous
                   1270:  * transfers - not ideal but so much easier.
                   1271:  * Actually, this is OK because it assures us that if we don't
                   1272:  * specifically ask for sync transfers, we won't do any.
                   1273:  */
                   1274: 
                   1275:                            write_3393_cmd(hostdata,WD_CMD_ASSERT_ATN); /* want MESS_OUT */
                   1276:                            hostdata->outgoing_msg[0] = EXTENDED_MESSAGE;
                   1277:                            hostdata->outgoing_msg[1] = 3;
                   1278:                            hostdata->outgoing_msg[2] = EXTENDED_SDTR;
                   1279:                            hostdata->outgoing_msg[3] = hostdata->default_sx_per/4;
                   1280:                            hostdata->outgoing_msg[4] = 0;
                   1281:                            hostdata->outgoing_len = 5;
                   1282:                            hostdata->sync_xfer[cmd->target] =
                   1283:                                        calc_sync_xfer(hostdata->default_sx_per/4,0);
                   1284:                            }
                   1285:                         else {
                   1286:                            hostdata->sync_xfer[cmd->target] = id;
                   1287:                            }
                   1288: #ifdef SYNC_DEBUG
                   1289: printk("sync_xfer=%02x",hostdata->sync_xfer[cmd->target]);
                   1290: #endif
                   1291:                         hostdata->sync_stat[cmd->target] = SS_SET;
                   1292:                         write_3393_cmd(hostdata,WD_CMD_NEGATE_ACK);
                   1293:                         hostdata->state = S_CONNECTED;
                   1294:                         break;
                   1295:                      case EXTENDED_WDTR:
                   1296:                         write_3393_cmd(hostdata,WD_CMD_ASSERT_ATN); /* want MESS_OUT */
                   1297:                         printk("sending WDTR ");
                   1298:                         hostdata->outgoing_msg[0] = EXTENDED_MESSAGE;
                   1299:                         hostdata->outgoing_msg[1] = 2;
                   1300:                         hostdata->outgoing_msg[2] = EXTENDED_WDTR;
                   1301:                         hostdata->outgoing_msg[3] = 0;   /* 8 bit transfer width */
                   1302:                         hostdata->outgoing_len = 4;
                   1303:                         write_3393_cmd(hostdata,WD_CMD_NEGATE_ACK);
                   1304:                         hostdata->state = S_CONNECTED;
                   1305:                         break;
                   1306:                      default:
                   1307:                         write_3393_cmd(hostdata,WD_CMD_ASSERT_ATN); /* want MESS_OUT */
                   1308:                         printk("Rejecting Unknown Extended Message(%02x). ",ucp[2]);
                   1309:                         hostdata->outgoing_msg[0] = MESSAGE_REJECT;
                   1310:                         hostdata->outgoing_len = 1;
                   1311:                         write_3393_cmd(hostdata,WD_CMD_NEGATE_ACK);
                   1312:                         hostdata->state = S_CONNECTED;
                   1313:                         break;
                   1314:                      }
                   1315:                   hostdata->incoming_ptr = 0;
                   1316:                   }
                   1317: 
                   1318:          /* We need to read more MESS_IN bytes for the extended message */
                   1319: 
                   1320:                else {
                   1321:                   hostdata->incoming_ptr++;
                   1322:                   write_3393_cmd(hostdata,WD_CMD_NEGATE_ACK);
                   1323:                   hostdata->state = S_CONNECTED;
                   1324:                   }
                   1325:                break;
                   1326: 
                   1327:             default:
                   1328:                printk("Rejecting Unknown Message(%02x) ",msg);
                   1329:                write_3393_cmd(hostdata,WD_CMD_ASSERT_ATN); /* want MESS_OUT */
                   1330:                hostdata->outgoing_msg[0] = MESSAGE_REJECT;
                   1331:                hostdata->outgoing_len = 1;
                   1332:                write_3393_cmd(hostdata,WD_CMD_NEGATE_ACK);
                   1333:                hostdata->state = S_CONNECTED;
                   1334:             }
                   1335:          break;
                   1336: 
                   1337: 
                   1338: /* Note: this interrupt will occur only after a LEVEL2 command */
                   1339: 
                   1340:       case CSR_SEL_XFER_DONE:
                   1341: 
                   1342: /* Make sure that reselection is enabled at this point - it may
                   1343:  * have been turned off for the command that just completed.
                   1344:  */
                   1345: 
                   1346:          write_3393(hostdata,WD_SOURCE_ID, SRCID_ER);
                   1347:          if (phs == 0x60) {
                   1348: DB(DB_INTR,printk("SX-DONE-%ld",cmd->pid))
                   1349:             cmd->SCp.Message = COMMAND_COMPLETE;
                   1350:             lun = read_3393(hostdata,WD_TARGET_LUN);
                   1351: DB(DB_INTR,printk(":%d.%d",cmd->SCp.Status,lun))
                   1352:             hostdata->connected = NULL;
                   1353:             hostdata->busy[cmd->target] &= ~(1 << cmd->lun);
                   1354:             hostdata->state = S_UNCONNECTED;
                   1355:             if (cmd->SCp.Status == ILLEGAL_STATUS_BYTE)
                   1356:                cmd->SCp.Status = lun;
                   1357:             if (cmd->cmnd[0] == REQUEST_SENSE && cmd->SCp.Status != GOOD)
                   1358:                cmd->result = (cmd->result & 0x00ffff) | (DID_ERROR << 16);
                   1359:             else
                   1360:                cmd->result = cmd->SCp.Status | (cmd->SCp.Message << 8);
                   1361:             cmd->scsi_done(cmd);
                   1362: 
                   1363: /* We are no longer connected to a target - check to see if
                   1364:  * there are commands waiting to be executed.
                   1365:  */
                   1366: 
                   1367:             in2000_execute(instance);
                   1368:             }
                   1369:          else {
                   1370:             printk("%02x:%02x:%02x-%ld: Unknown SEL_XFER_DONE phase!!---",asr,sr,phs,cmd->pid);
                   1371:             }
                   1372:          break;
                   1373: 
                   1374: 
                   1375: /* Note: this interrupt will occur only after a LEVEL2 command */
                   1376: 
                   1377:       case CSR_SDP:
                   1378: DB(DB_INTR,printk("SDP"))
                   1379:             hostdata->state = S_RUNNING_LEVEL2;
                   1380:             write_3393(hostdata,WD_COMMAND_PHASE, 0x41);
                   1381:             write_3393_cmd(hostdata,WD_CMD_SEL_ATN_XFER);
                   1382:          break;
                   1383: 
                   1384: 
                   1385:       case CSR_XFER_DONE|PHS_MESS_OUT:
                   1386:       case CSR_UNEXP    |PHS_MESS_OUT:
                   1387:       case CSR_SRV_REQ  |PHS_MESS_OUT:
                   1388: DB(DB_INTR,printk("MSG_OUT="))
                   1389: 
                   1390: /* To get here, we've probably requested MESSAGE_OUT and have
                   1391:  * already put the correct bytes in outgoing_msg[] and filled
                   1392:  * in outgoing_len. We simply send them out to the SCSI bus.
                   1393:  * Sometimes we get MESSAGE_OUT phase when we're not expecting
                   1394:  * it - like when our SDTR message is rejected by a target. Some
                   1395:  * targets send the REJECT before receiving all of the extended
                   1396:  * message, and then seem to go back to MESSAGE_OUT for a byte
                   1397:  * or two. Not sure why, or if I'm doing something wrong to
                   1398:  * cause this to happen. Regardless, it seems that sending
                   1399:  * NOP messages in these situations results in no harm and
                   1400:  * makes everyone happy.
                   1401:  */
                   1402: 
                   1403:          if (hostdata->outgoing_len == 0) {
                   1404:             hostdata->outgoing_len = 1;
                   1405:             hostdata->outgoing_msg[0] = NOP;
                   1406:             }
                   1407:          transfer_pio(hostdata->outgoing_msg, hostdata->outgoing_len,
                   1408:                       DATA_OUT_DIR, hostdata);
                   1409: DB(DB_INTR,printk("%02x",hostdata->outgoing_msg[0]))
                   1410:          hostdata->outgoing_len = 0;
                   1411:          hostdata->state = S_CONNECTED;
                   1412:          break;
                   1413: 
                   1414:  
                   1415:       case CSR_UNEXP_DISC:
                   1416: 
                   1417: /* I think I've seen this after a request-sense that was in response
                   1418:  * to an error condition, but not sure. We certainly need to do
                   1419:  * something when we get this interrupt - the question is 'what?'.
                   1420:  * Let's think positively, and assume some command has finished
                   1421:  * in a legal manner (like a command that provokes a request-sense),
                   1422:  * so we treat it as a normal command-complete-disconnect.
                   1423:  */
                   1424: 
                   1425: 
                   1426: /* Make sure that reselection is enabled at this point - it may
                   1427:  * have been turned off for the command that just completed.
                   1428:  */
                   1429: 
                   1430:          write_3393(hostdata,WD_SOURCE_ID, SRCID_ER);
                   1431:          if (cmd == NULL) {
                   1432:             printk(" - Already disconnected! ");
                   1433:             hostdata->state = S_UNCONNECTED;
                   1434: 
                   1435: /* release the SMP spin_lock and restore irq state */
                   1436:             CLISPIN_UNLOCK(flags);
                   1437:             return;
                   1438:             }
                   1439: DB(DB_INTR,printk("UNEXP_DISC-%ld",cmd->pid))
                   1440:          hostdata->connected = NULL;
                   1441:          hostdata->busy[cmd->target] &= ~(1 << cmd->lun);
                   1442:          hostdata->state = S_UNCONNECTED;
                   1443:          if (cmd->cmnd[0] == REQUEST_SENSE && cmd->SCp.Status != GOOD)
                   1444:             cmd->result = (cmd->result & 0x00ffff) | (DID_ERROR << 16);
                   1445:          else
                   1446:             cmd->result = cmd->SCp.Status | (cmd->SCp.Message << 8);
                   1447:          cmd->scsi_done(cmd);
                   1448: 
                   1449: /* We are no longer connected to a target - check to see if
                   1450:  * there are commands waiting to be executed.
                   1451:  */
                   1452: 
                   1453:          in2000_execute(instance);
                   1454:          break;
                   1455: 
                   1456: 
                   1457:       case CSR_DISC:
                   1458: 
                   1459: /* Make sure that reselection is enabled at this point - it may
                   1460:  * have been turned off for the command that just completed.
                   1461:  */
                   1462: 
                   1463:          write_3393(hostdata,WD_SOURCE_ID, SRCID_ER);
                   1464: DB(DB_INTR,printk("DISC-%ld",cmd->pid))
                   1465:          if (cmd == NULL) {
                   1466:             printk(" - Already disconnected! ");
                   1467:             hostdata->state = S_UNCONNECTED;
                   1468:             }
                   1469:          switch (hostdata->state) {
                   1470:             case S_PRE_CMP_DISC:
                   1471:                hostdata->connected = NULL;
                   1472:                hostdata->busy[cmd->target] &= ~(1 << cmd->lun);
                   1473:                hostdata->state = S_UNCONNECTED;
                   1474: DB(DB_INTR,printk(":%d",cmd->SCp.Status))
                   1475:                if (cmd->cmnd[0] == REQUEST_SENSE && cmd->SCp.Status != GOOD)
                   1476:                   cmd->result = (cmd->result & 0x00ffff) | (DID_ERROR << 16);
                   1477:                else
                   1478:                   cmd->result = cmd->SCp.Status | (cmd->SCp.Message << 8);
                   1479:                cmd->scsi_done(cmd);
                   1480:                break;
                   1481:             case S_PRE_TMP_DISC:
                   1482:             case S_RUNNING_LEVEL2:
                   1483:                cmd->host_scribble = (uchar *)hostdata->disconnected_Q;
                   1484:                hostdata->disconnected_Q = cmd;
                   1485:                hostdata->connected = NULL;
                   1486:                hostdata->state = S_UNCONNECTED;
                   1487: 
                   1488: #ifdef PROC_STATISTICS
                   1489:                hostdata->disc_done_cnt[cmd->target]++;
                   1490: #endif
                   1491: 
                   1492:                break;
                   1493:             default:
                   1494:                printk("*** Unexpected DISCONNECT interrupt! ***");
                   1495:                hostdata->state = S_UNCONNECTED;
                   1496:             }
                   1497: 
                   1498: /* We are no longer connected to a target - check to see if
                   1499:  * there are commands waiting to be executed.
                   1500:  */
                   1501: 
                   1502:          in2000_execute(instance);
                   1503:          break;
                   1504: 
                   1505: 
                   1506:       case CSR_RESEL_AM:
                   1507: DB(DB_INTR,printk("RESEL"))
                   1508: 
                   1509:    /* First we have to make sure this reselection didn't */
                   1510:    /* happen during Arbitration/Selection of some other device. */
                   1511:    /* If yes, put losing command back on top of input_Q. */
                   1512: 
                   1513:          if (hostdata->level2 <= L2_NONE) {
                   1514: 
                   1515:             if (hostdata->selecting) {
                   1516:                cmd = (Scsi_Cmnd *)hostdata->selecting;
                   1517:                hostdata->selecting = NULL;
                   1518:                hostdata->busy[cmd->target] &= ~(1 << cmd->lun);
                   1519:                cmd->host_scribble = (uchar *)hostdata->input_Q;
                   1520:                hostdata->input_Q = cmd;
                   1521:                }
                   1522:             }
                   1523: 
                   1524:          else {
                   1525: 
                   1526:             if (cmd) {
                   1527:                if (phs == 0x00) {
                   1528:                   hostdata->busy[cmd->target] &= ~(1 << cmd->lun);
                   1529:                   cmd->host_scribble = (uchar *)hostdata->input_Q;
                   1530:                   hostdata->input_Q = cmd;
                   1531:                   }
                   1532:                else {
                   1533:                   printk("---%02x:%02x:%02x-TROUBLE: Intrusive ReSelect!---",asr,sr,phs);
                   1534:                   while (1)
                   1535:                      printk("\r");
                   1536:                   }
                   1537:                }
                   1538: 
                   1539:             }
                   1540: 
                   1541:    /* OK - find out which device reselected us. */
                   1542: 
                   1543:          id = read_3393(hostdata,WD_SOURCE_ID);
                   1544:          id &= SRCID_MASK;
                   1545: 
                   1546:    /* and extract the lun from the ID message. (Note that we don't
                   1547:     * bother to check for a valid message here - I guess this is
                   1548:     * not the right way to go, but....)
                   1549:     */
                   1550: 
                   1551:          lun = read_3393(hostdata,WD_DATA);
                   1552:          if (hostdata->level2 < L2_RESELECT)
                   1553:             write_3393_cmd(hostdata,WD_CMD_NEGATE_ACK);
                   1554:          lun &= 7;
                   1555: 
                   1556:    /* Now we look for the command that's reconnecting. */
                   1557: 
                   1558:          cmd = (Scsi_Cmnd *)hostdata->disconnected_Q;
                   1559:          patch = NULL;
                   1560:          while (cmd) {
                   1561:             if (id == cmd->target && lun == cmd->lun)
                   1562:                break;
                   1563:             patch = cmd;
                   1564:             cmd = (Scsi_Cmnd *)cmd->host_scribble;
                   1565:             }
                   1566: 
                   1567:    /* Hmm. Couldn't find a valid command.... What to do? */
                   1568: 
                   1569:          if (!cmd) {
                   1570:             printk("---TROUBLE: target %d.%d not in disconnect queue---",id,lun);
                   1571:             break;
                   1572:             }
                   1573: 
                   1574:    /* Ok, found the command - now start it up again. */
                   1575: 
                   1576:          if (patch)
                   1577:             patch->host_scribble = cmd->host_scribble;
                   1578:          else
                   1579:             hostdata->disconnected_Q = (Scsi_Cmnd *)cmd->host_scribble;
                   1580:          hostdata->connected = cmd;
                   1581: 
                   1582:    /* We don't need to worry about 'initialize_SCp()' or 'hostdata->busy[]'
                   1583:     * because these things are preserved over a disconnect.
                   1584:     * But we DO need to fix the DPD bit so it's correct for this command.
                   1585:     */
                   1586: 
                   1587:          if (is_dir_out(cmd))
                   1588:             write_3393(hostdata,WD_DESTINATION_ID,cmd->target);
                   1589:          else
                   1590:             write_3393(hostdata,WD_DESTINATION_ID,cmd->target | DSTID_DPD);
                   1591:          if (hostdata->level2 >= L2_RESELECT) {
                   1592:             write_3393_count(hostdata,0); /* we want a DATA_PHASE interrupt */
                   1593:             write_3393(hostdata,WD_COMMAND_PHASE, 0x45);
                   1594:             write_3393_cmd(hostdata,WD_CMD_SEL_ATN_XFER);
                   1595:             hostdata->state = S_RUNNING_LEVEL2;
                   1596:             }
                   1597:          else
                   1598:             hostdata->state = S_CONNECTED;
                   1599: 
                   1600: DB(DB_INTR,printk("-%ld",cmd->pid))
                   1601:          break;
                   1602: 
                   1603:       default:
                   1604:          printk("--UNKNOWN INTERRUPT:%02x:%02x:%02x--",asr,sr,phs);
                   1605:       }
                   1606: 
                   1607:    write1_io(0, IO_LED_OFF);
                   1608: 
                   1609: DB(DB_INTR,printk("} "))
                   1610: 
                   1611: /* release the SMP spin_lock and restore irq state */
                   1612:    CLISPIN_UNLOCK(flags);
                   1613: 
                   1614: }
                   1615: 
                   1616: 
                   1617: 
                   1618: #define RESET_CARD         0
                   1619: #define RESET_CARD_AND_BUS 1
                   1620: #define B_FLAG 0x80
                   1621: 
                   1622: static int reset_hardware(struct Scsi_Host *instance, int type)
                   1623: {
                   1624: struct IN2000_hostdata *hostdata;
                   1625: int qt,x;
                   1626: unsigned long flags;
                   1627: 
                   1628:    hostdata = (struct IN2000_hostdata *)instance->hostdata;
                   1629: 
                   1630:    write1_io(0, IO_LED_ON);
                   1631:    if (type == RESET_CARD_AND_BUS) {
                   1632:       write1_io(0,IO_CARD_RESET);
                   1633:       x = read1_io(IO_HARDWARE);
                   1634:       }
                   1635:    x = read_3393(hostdata,WD_SCSI_STATUS);   /* clear any WD intrpt */
                   1636:    write_3393(hostdata,WD_OWN_ID, instance->this_id |
                   1637:                            OWNID_EAF | OWNID_RAF | OWNID_FS_8);
                   1638:    write_3393(hostdata,WD_CONTROL, CTRL_IDI | CTRL_EDI | CTRL_POLLED);
                   1639:    write_3393(hostdata,WD_SYNCHRONOUS_TRANSFER,
                   1640:               calc_sync_xfer(hostdata->default_sx_per/4,DEFAULT_SX_OFF));
                   1641:    save_flags(flags);
                   1642:    cli();
                   1643:    write1_io(0,IO_FIFO_WRITE);            /* clear fifo counter */
                   1644:    write1_io(0,IO_FIFO_READ);             /* start fifo out in read mode */
                   1645:    write_3393(hostdata,WD_COMMAND, WD_CMD_RESET);
                   1646:    while (!(READ_AUX_STAT() & ASR_INT))
                   1647:       ;                                   /* wait for RESET to complete */
                   1648: 
                   1649:    x = read_3393(hostdata,WD_SCSI_STATUS);   /* clear interrupt */
                   1650:    restore_flags(flags);
                   1651:    write_3393(hostdata,WD_QUEUE_TAG,0xa5);   /* any random number */
                   1652:    qt = read_3393(hostdata,WD_QUEUE_TAG);
                   1653:    if (qt == 0xa5) {
                   1654:       x |= B_FLAG;
                   1655:       write_3393(hostdata,WD_QUEUE_TAG,0);
                   1656:       }
                   1657:    write_3393(hostdata,WD_TIMEOUT_PERIOD, TIMEOUT_PERIOD_VALUE);
                   1658:    write_3393(hostdata,WD_CONTROL, CTRL_IDI | CTRL_EDI | CTRL_POLLED);
                   1659:    write1_io(0, IO_LED_OFF);
                   1660:    return x;
                   1661: }
                   1662: 
                   1663: 
                   1664: 
                   1665: int in2000_reset(Scsi_Cmnd *cmd, unsigned int reset_flags)
                   1666: {
                   1667: unsigned long flags;
                   1668: struct Scsi_Host *instance;
                   1669: struct IN2000_hostdata *hostdata;
                   1670: int x;
                   1671: 
                   1672:    instance = cmd->host;
                   1673:    hostdata = (struct IN2000_hostdata *)instance->hostdata;
                   1674: 
                   1675:    printk("scsi%d: Reset. ", instance->host_no);
                   1676:    save_flags(flags);
                   1677:    cli();
                   1678: 
                   1679:    /* do scsi-reset here */
                   1680: 
                   1681:    reset_hardware(instance, RESET_CARD_AND_BUS);
                   1682:    for (x = 0; x < 8; x++) {
                   1683:       hostdata->busy[x] = 0;
                   1684:       hostdata->sync_xfer[x] = calc_sync_xfer(DEFAULT_SX_PER/4,DEFAULT_SX_OFF);
                   1685:       hostdata->sync_stat[x] = SS_UNSET;  /* using default sync values */
                   1686:       }
                   1687:    hostdata->input_Q = NULL;
                   1688:    hostdata->selecting = NULL;
                   1689:    hostdata->connected = NULL;
                   1690:    hostdata->disconnected_Q = NULL;
                   1691:    hostdata->state = S_UNCONNECTED;
                   1692:    hostdata->fifo = FI_FIFO_UNUSED;
                   1693:    hostdata->incoming_ptr = 0;
                   1694:    hostdata->outgoing_len = 0;
                   1695: 
                   1696:    cmd->result = DID_RESET << 16;
                   1697:    restore_flags(flags);
                   1698:    return 0;
                   1699: }
                   1700: 
                   1701: 
                   1702: 
                   1703: int in2000_abort (Scsi_Cmnd *cmd)
                   1704: {
                   1705: struct Scsi_Host *instance;
                   1706: struct IN2000_hostdata *hostdata;
                   1707: Scsi_Cmnd *tmp, *prev;
                   1708: unsigned long flags;
                   1709: uchar sr, asr;
                   1710: unsigned long timeout;
                   1711: 
                   1712:    save_flags (flags);
                   1713:    cli();
                   1714: 
                   1715:    instance = cmd->host;
                   1716:    hostdata = (struct IN2000_hostdata *)instance->hostdata;
                   1717: 
                   1718:    printk ("scsi%d: Abort-", instance->host_no);
                   1719:    printk("(asr=%02x,count=%ld,resid=%d,buf_resid=%d,have_data=%d,FC=%02x)- ",
                   1720:             READ_AUX_STAT(),read_3393_count(hostdata),cmd->SCp.this_residual,cmd->SCp.buffers_residual,
                   1721:             cmd->SCp.have_data_in,read1_io(IO_FIFO_COUNT));
                   1722: 
                   1723: /*
                   1724:  * Case 1 : If the command hasn't been issued yet, we simply remove it
                   1725:  *     from the inout_Q.
                   1726:  */
                   1727: 
                   1728:    tmp = (Scsi_Cmnd *)hostdata->input_Q;
                   1729:    prev = 0;
                   1730:    while (tmp) {
                   1731:       if (tmp == cmd) {
                   1732:          if (prev)
                   1733:             prev->host_scribble = cmd->host_scribble;
                   1734:          cmd->host_scribble = NULL;
                   1735:          cmd->result = DID_ABORT << 16;
                   1736:          printk("scsi%d: Abort - removing command %ld from input_Q. ",
                   1737:            instance->host_no, cmd->pid);
                   1738:          cmd->scsi_done(cmd);
                   1739:          restore_flags(flags);
                   1740:          return SCSI_ABORT_SUCCESS;
                   1741:          }
                   1742:       prev = tmp;
                   1743:       tmp = (Scsi_Cmnd *)tmp->host_scribble;
                   1744:       }
                   1745: 
                   1746: /*
                   1747:  * Case 2 : If the command is connected, we're going to fail the abort
                   1748:  *     and let the high level SCSI driver retry at a later time or
                   1749:  *     issue a reset.
                   1750:  *
                   1751:  *     Timeouts, and therefore aborted commands, will be highly unlikely
                   1752:  *     and handling them cleanly in this situation would make the common
                   1753:  *     case of noresets less efficient, and would pollute our code.  So,
                   1754:  *     we fail.
                   1755:  */
                   1756: 
                   1757:    if (hostdata->connected == cmd) {
                   1758: 
                   1759:       printk("scsi%d: Aborting connected command %ld - ",
                   1760:               instance->host_no, cmd->pid);
                   1761: 
                   1762:       printk("sending wd33c93 ABORT command - ");
                   1763:       write_3393(hostdata, WD_CONTROL, CTRL_IDI | CTRL_EDI | CTRL_POLLED);
                   1764:       write_3393_cmd(hostdata, WD_CMD_ABORT);
                   1765: 
                   1766: /* Now we have to attempt to flush out the FIFO... */
                   1767: 
                   1768:       printk("flushing fifo - ");
                   1769:       timeout = 1000000;
                   1770:       do {
                   1771:          asr = READ_AUX_STAT();
                   1772:          if (asr & ASR_DBR)
                   1773:             read_3393(hostdata, WD_DATA);
                   1774:          } while (!(asr & ASR_INT) && timeout-- > 0);
                   1775:       sr = read_3393(hostdata, WD_SCSI_STATUS);
                   1776:       printk("asr=%02x, sr=%02x, %ld bytes un-transferred (timeout=%ld) - ",
                   1777:              asr, sr, read_3393_count(hostdata), timeout);
                   1778: 
                   1779:    /*
                   1780:     * Abort command processed.
                   1781:     * Still connected.
                   1782:     * We must disconnect.
                   1783:     */
                   1784: 
                   1785:       printk("sending wd33c93 DISCONNECT command - ");
                   1786:       write_3393_cmd(hostdata, WD_CMD_DISCONNECT);
                   1787: 
                   1788:       timeout = 1000000;
                   1789:       asr = READ_AUX_STAT();
                   1790:       while ((asr & ASR_CIP) && timeout-- > 0)
                   1791:          asr = READ_AUX_STAT();
                   1792:       sr = read_3393(hostdata, WD_SCSI_STATUS);
                   1793:       printk("asr=%02x, sr=%02x.",asr,sr);
                   1794: 
                   1795:       hostdata->busy[cmd->target] &= ~(1 << cmd->lun);
                   1796:       hostdata->connected = NULL;
                   1797:       hostdata->state = S_UNCONNECTED;
                   1798:       cmd->result = DID_ABORT << 16;
                   1799:       cmd->scsi_done(cmd);
                   1800: 
                   1801:       in2000_execute (instance);
                   1802: 
                   1803:       restore_flags(flags);
                   1804:       return SCSI_ABORT_SUCCESS;
                   1805:       }
                   1806: 
                   1807: /*
                   1808:  * Case 3: If the command is currently disconnected from the bus,
                   1809:  * we're not going to expend much effort here: Let's just return
                   1810:  * an ABORT_SNOOZE and hope for the best...
                   1811:  */
                   1812: 
                   1813:    for (tmp=(Scsi_Cmnd *)hostdata->disconnected_Q; tmp;
                   1814:          tmp=(Scsi_Cmnd *)tmp->host_scribble)
                   1815:       if (cmd == tmp) {
                   1816:          restore_flags(flags);
                   1817:          printk("Sending ABORT_SNOOZE. ");
                   1818:          return SCSI_ABORT_SNOOZE;
                   1819:          }
                   1820: 
                   1821: /*
                   1822:  * Case 4 : If we reached this point, the command was not found in any of
                   1823:  *     the queues.
                   1824:  *
                   1825:  * We probably reached this point because of an unlikely race condition
                   1826:  * between the command completing successfully and the abortion code,
                   1827:  * so we won't panic, but we will notify the user in case something really
                   1828:  * broke.
                   1829:  */
                   1830: 
                   1831:    in2000_execute (instance);
                   1832: 
                   1833:    restore_flags(flags);
                   1834:    printk("scsi%d: warning : SCSI command probably completed successfully"
                   1835:       "         before abortion. ", instance->host_no);
                   1836:    return SCSI_ABORT_NOT_RUNNING;
                   1837: }
                   1838: 
                   1839: 
                   1840: 
                   1841: #define MAX_IN2000_HOSTS 3
                   1842: #define MAX_SETUP_ARGS (sizeof(setup_args) / sizeof(char *))
                   1843: #define SETUP_BUFFER_SIZE 200
                   1844: static char setup_buffer[SETUP_BUFFER_SIZE];
                   1845: static char setup_used[MAX_SETUP_ARGS];
                   1846: static int done_setup = 0;
                   1847: 
                   1848: in2000__INITFUNC( void in2000_setup (char *str, int *ints) )
                   1849: {
                   1850: int i;
                   1851: char *p1,*p2;
                   1852: 
                   1853:    strncpy(setup_buffer,str,SETUP_BUFFER_SIZE);
                   1854:    setup_buffer[SETUP_BUFFER_SIZE - 1] = '\0';
                   1855:    p1 = setup_buffer;
                   1856:    i = 0;
                   1857:    while (*p1 && (i < MAX_SETUP_ARGS)) {
                   1858:       p2 = strchr(p1, ',');
                   1859:       if (p2) {
                   1860:          *p2 = '\0';
                   1861:          if (p1 != p2)
                   1862:             setup_args[i] = p1;
                   1863:          p1 = p2 + 1;
                   1864:          i++;
                   1865:          }
                   1866:       else {
                   1867:          setup_args[i] = p1;
                   1868:          break;
                   1869:          }
                   1870:       }
                   1871:    for (i=0; i<MAX_SETUP_ARGS; i++)
                   1872:       setup_used[i] = 0;
                   1873:    done_setup = 1;
                   1874: }
                   1875: 
                   1876: 
                   1877: /* check_setup_args() returns index if key found, 0 if not
                   1878:  */
                   1879: 
                   1880: in2000__INITFUNC( static int check_setup_args(char *key, int *flags, int *val, char *buf) )
                   1881: {
                   1882: int x;
                   1883: char *cp;
                   1884: 
                   1885:    for  (x=0; x<MAX_SETUP_ARGS; x++) {
                   1886:       if (setup_used[x])
                   1887:          continue;
                   1888:       if (!strncmp(setup_args[x], key, strlen(key)))
                   1889:          break;
                   1890:       }
                   1891:    if (x == MAX_SETUP_ARGS)
                   1892:       return 0;
                   1893:    setup_used[x] = 1;
                   1894:    cp = setup_args[x] + strlen(key);
                   1895:    *val = -1;
                   1896:    if (*cp != ':')
                   1897:       return ++x;
                   1898:    cp++;
                   1899:    if ((*cp >= '0') && (*cp <= '9')) {
                   1900:       *val = simple_strtoul(cp,NULL,0);
                   1901:       }
                   1902:    return ++x;
                   1903: }
                   1904: 
                   1905: 
                   1906: 
                   1907: /* The "correct" (ie portable) way to access memory-mapped hardware
                   1908:  * such as the IN2000 EPROM and dip switch is through the use of
                   1909:  * special macros declared in 'asm/io.h'. We use readb() and readl()
                   1910:  * when reading from the card's BIOS area in in2000_detect().
                   1911:  */
                   1912: static const unsigned int *bios_tab[] in2000__INITDATA = {
                   1913:    (unsigned int *)0xc8000,
                   1914:    (unsigned int *)0xd0000,
                   1915:    (unsigned int *)0xd8000,
                   1916:    0
                   1917:    };
                   1918: 
                   1919: static const unsigned short base_tab[] in2000__INITDATA = {
                   1920:    0x220,
                   1921:    0x200,
                   1922:    0x110,
                   1923:    0x100,
                   1924:    };
                   1925: 
                   1926: static const int int_tab[] in2000__INITDATA = {
                   1927:    15,
                   1928:    14,
                   1929:    11,
                   1930:    10
                   1931:    };
                   1932: 
                   1933: 
                   1934: in2000__INITFUNC( int in2000_detect(Scsi_Host_Template * tpnt) )
                   1935: {
                   1936: struct Scsi_Host *instance;
                   1937: struct IN2000_hostdata *hostdata;
                   1938: int detect_count;
                   1939: int bios;
                   1940: int x;
                   1941: unsigned short base;
                   1942: uchar switches;
                   1943: uchar hrev;
                   1944: int flags;
                   1945: int val;
                   1946: char buf[32];
                   1947: 
                   1948: /* Thanks to help from Bill Earnest, probing for IN2000 cards is a
                   1949:  * pretty straightforward and fool-proof operation. There are 3
                   1950:  * possible locations for the IN2000 EPROM in memory space - if we
                   1951:  * find a BIOS signature, we can read the dip switch settings from
                   1952:  * the byte at BIOS+32 (shadowed in by logic on the card). From 2
                   1953:  * of the switch bits we get the card's address in IO space. There's
                   1954:  * an image of the dip switch there, also, so we have a way to back-
                   1955:  * check that this really is an IN2000 card. Very nifty. Use the
                   1956:  * 'ioport:xx' command-line parameter if your BIOS EPROM is absent
                   1957:  * or disabled.
                   1958:  */
                   1959: 
                   1960:    if (!done_setup && setup_strings)
                   1961:       in2000_setup(setup_strings,0);
                   1962: 
                   1963:    detect_count = 0;
                   1964:    for (bios = 0; bios_tab[bios]; bios++) {
                   1965:       if (check_setup_args("ioport",&flags,&val,buf)) {
                   1966:          base = val;
                   1967:          switches = ~inb(base + IO_SWITCHES) & 0xff;
                   1968:          printk("Forcing IN2000 detection at IOport 0x%x ",base);
                   1969:          bios = 2;
                   1970:          }
                   1971: /*
                   1972:  * There have been a couple of BIOS versions with different layouts
                   1973:  * for the obvious ID strings. We look for the 2 most common ones and
                   1974:  * hope that they cover all the cases...
                   1975:  */
                   1976:       else if (readl(bios_tab[bios]+0x04) == 0x41564f4e ||
                   1977:                readl(bios_tab[bios]+0x0c) == 0x61776c41) {
                   1978:          printk("Found IN2000 BIOS at 0x%x ",(unsigned int)bios_tab[bios]);
                   1979: 
                   1980: /* Read the switch image that's mapped into EPROM space */
                   1981: 
                   1982:          switches = ~((readb(bios_tab[bios]+0x08) & 0xff));
                   1983: 
                   1984: /* Find out where the IO space is */
                   1985: 
                   1986:          x = switches & (SW_ADDR0 | SW_ADDR1);
                   1987:          base = base_tab[x];
                   1988: 
                   1989: /* Check for the IN2000 signature in IO space. */
                   1990: 
                   1991:          x = ~inb(base + IO_SWITCHES) & 0xff;
                   1992:          if (x != switches) {
                   1993:             printk("Bad IO signature: %02x vs %02x.\n",x,switches);
                   1994:             continue;
                   1995:             }
                   1996:          }
                   1997:       else
                   1998:          continue;
                   1999: 
                   2000: /* OK. We have a base address for the IO ports - run a few safety checks */
                   2001: 
                   2002:       if (!(switches & SW_BIT7)) {        /* I _think_ all cards do this */
                   2003:          printk("There is no IN-2000 SCSI card at IOport 0x%03x!\n",base);
                   2004:          continue;
                   2005:          }
                   2006: 
                   2007: /* Let's assume any hardware version will work, although the driver
                   2008:  * has only been tested on 0x21, 0x22, 0x25, 0x26, and 0x27. We'll
                   2009:  * print out the rev number for reference later, but accept them all.
                   2010:  */
                   2011: 
                   2012:       hrev = inb(base + IO_HARDWARE);
                   2013: 
                   2014:   /* Bit 2 tells us if interrupts are disabled */
                   2015:       if (switches & SW_DISINT) {
                   2016:          printk("The IN-2000 SCSI card at IOport 0x%03x ",base);
                   2017:          printk("is not configured for interrupt operation!\n");
                   2018:          printk("This driver requires an interrupt: cancelling detection.\n");
                   2019:          continue;
                   2020:          }
                   2021: 
                   2022: /* Ok. We accept that there's an IN2000 at ioaddr 'base'. Now
                   2023:  * initialize it.
                   2024:  */
                   2025: 
                   2026:       tpnt->proc_dir = &proc_scsi_in2000; /* done more than once? harmless. */
                   2027:       detect_count++;
                   2028:       instance  = scsi_register(tpnt, sizeof(struct IN2000_hostdata));
                   2029:       if (!instance_list)
                   2030:          instance_list = instance;
                   2031:       hostdata = (struct IN2000_hostdata *)instance->hostdata;
                   2032:       instance->io_port = hostdata->io_base = base;
                   2033:       hostdata->dip_switch = switches;
                   2034:       hostdata->hrev = hrev;
                   2035: 
                   2036:       write1_io(0,IO_FIFO_WRITE);            /* clear fifo counter */
                   2037:       write1_io(0,IO_FIFO_READ);             /* start fifo out in read mode */
                   2038:       write1_io(0,IO_INTR_MASK);    /* allow all ints */
                   2039:       x = int_tab[(switches & (SW_INT0 | SW_INT1)) >> SW_INT_SHIFT];
                   2040:       if (request_irq(x, in2000_intr, SA_INTERRUPT, "in2000", NULL)) {
                   2041:          printk("in2000_detect: Unable to allocate IRQ.\n");
                   2042:          detect_count--;
                   2043:          continue;
                   2044:          }
                   2045:       instance->irq = x;
                   2046:       instance->n_io_port = 13;
                   2047:       request_region(base, 13, "in2000"); /* lock in this IO space for our use */
                   2048: 
                   2049:       for (x = 0; x < 8; x++) {
                   2050:          hostdata->busy[x] = 0;
                   2051:          hostdata->sync_xfer[x] = calc_sync_xfer(DEFAULT_SX_PER/4,DEFAULT_SX_OFF);
                   2052:          hostdata->sync_stat[x] = SS_UNSET;  /* using default sync values */
                   2053: #ifdef PROC_STATISTICS
                   2054:          hostdata->cmd_cnt[x] = 0;
                   2055:          hostdata->disc_allowed_cnt[x] = 0;
                   2056:          hostdata->disc_done_cnt[x] = 0;
                   2057: #endif
                   2058:          }
                   2059:       hostdata->input_Q = NULL;
                   2060:       hostdata->selecting = NULL;
                   2061:       hostdata->connected = NULL;
                   2062:       hostdata->disconnected_Q = NULL;
                   2063:       hostdata->state = S_UNCONNECTED;
                   2064:       hostdata->fifo = FI_FIFO_UNUSED;
                   2065:       hostdata->level2 = L2_BASIC;
                   2066:       hostdata->disconnect = DIS_ADAPTIVE;
                   2067:       hostdata->args = DEBUG_DEFAULTS;
                   2068:       hostdata->incoming_ptr = 0;
                   2069:       hostdata->outgoing_len = 0;
                   2070:       hostdata->default_sx_per = DEFAULT_SX_PER;
                   2071: 
                   2072: /* Older BIOS's had a 'sync on/off' switch - use its setting */
                   2073: 
                   2074:       if (readl(bios_tab[bios]+0x04) == 0x41564f4e && (switches & SW_SYNC_DOS5))
                   2075:          hostdata->sync_off = 0x00;    /* sync defaults to on */
                   2076:       else
                   2077:          hostdata->sync_off = 0xff;    /* sync defaults to off */
                   2078: 
                   2079: #ifdef PROC_INTERFACE
                   2080:       hostdata->proc = PR_VERSION|PR_INFO|PR_STATISTICS|
                   2081:                        PR_CONNECTED|PR_INPUTQ|PR_DISCQ|
                   2082:                        PR_STOP;
                   2083: #ifdef PROC_STATISTICS
                   2084:       hostdata->int_cnt = 0;
                   2085: #endif
                   2086: #endif
                   2087: 
                   2088:       if (check_setup_args("nosync",&flags,&val,buf))
                   2089:          hostdata->sync_off = val;
                   2090: 
                   2091:       if (check_setup_args("period",&flags,&val,buf))
                   2092:          hostdata->default_sx_per = sx_table[round_period((unsigned int)val)].period_ns;
                   2093: 
                   2094:       if (check_setup_args("disconnect",&flags,&val,buf)) {
                   2095:          if ((val >= DIS_NEVER) && (val <= DIS_ALWAYS))
                   2096:             hostdata->disconnect = val;
                   2097:          else
                   2098:             hostdata->disconnect = DIS_ADAPTIVE;
                   2099:          }
                   2100: 
                   2101:       if (check_setup_args("noreset",&flags,&val,buf))
                   2102:          hostdata->args ^= A_NO_SCSI_RESET;
                   2103: 
                   2104:       if (check_setup_args("level2",&flags,&val,buf))
                   2105:          hostdata->level2 = val;
                   2106: 
                   2107:       if (check_setup_args("debug",&flags,&val,buf))
                   2108:          hostdata->args = (val & DB_MASK);
                   2109: 
                   2110: #ifdef PROC_INTERFACE
                   2111:       if (check_setup_args("proc",&flags,&val,buf))
                   2112:          hostdata->proc = val;
                   2113: #endif
                   2114: 
                   2115: 
                   2116:       x = reset_hardware(instance,(hostdata->args & A_NO_SCSI_RESET)?RESET_CARD:RESET_CARD_AND_BUS);
                   2117: 
                   2118:       hostdata->microcode = read_3393(hostdata,WD_CDB_1);
                   2119:       if (x & 0x01) {
                   2120:          if (x & B_FLAG)
                   2121:             hostdata->chip = C_WD33C93B;
                   2122:          else
                   2123:             hostdata->chip = C_WD33C93A;
                   2124:          }
                   2125:       else
                   2126:          hostdata->chip = C_WD33C93;
                   2127: 
                   2128:       printk("dip_switch=%02x irq=%d ioport=%02x floppy=%s sync/DOS5=%s ",
                   2129:                   (switches & 0x7f),
                   2130:                   instance->irq,hostdata->io_base,
                   2131:                   (switches & SW_FLOPPY)?"Yes":"No",
                   2132:                   (switches & SW_SYNC_DOS5)?"Yes":"No");
                   2133:       printk("hardware_ver=%02x chip=%s microcode=%02x\n",
                   2134:                   hrev,
                   2135:                   (hostdata->chip==C_WD33C93)?"WD33c93":
                   2136:                   (hostdata->chip==C_WD33C93A)?"WD33c93A":
                   2137:                   (hostdata->chip==C_WD33C93B)?"WD33c93B":"unknown",
                   2138:                   hostdata->microcode);
                   2139: #ifdef DEBUGGING_ON
                   2140:       printk("setup_args = ");
                   2141:       for (x=0; x<MAX_SETUP_ARGS; x++)
                   2142:          printk("%s,",setup_args[x]);
                   2143:       printk("\n");
                   2144: #endif
                   2145:       if (hostdata->sync_off == 0xff)
                   2146:          printk("Sync-transfer DISABLED on all devices: ENABLE from command-line\n");
                   2147:       printk("IN2000 driver version %s - %s\n",IN2000_VERSION,IN2000_DATE);
                   2148:       }
                   2149: 
                   2150:    return detect_count;
                   2151: }
                   2152: 
                   2153: 
                   2154: /* NOTE: I lifted this function straight out of the old driver,
                   2155:  *       and have not tested it. Presumably it does what it's
                   2156:  *       supposed to do...
                   2157:  */
                   2158: 
                   2159: int in2000_biosparam(Disk *disk, kdev_t dev, int *iinfo)
                   2160: {
                   2161: int size;
                   2162: 
                   2163:    size  = disk->capacity;
                   2164:    iinfo[0] = 64;
                   2165:    iinfo[1] = 32;
                   2166:    iinfo[2] = size >> 11;
                   2167: 
                   2168: /* This should approximate the large drive handling that the DOS ASPI manager
                   2169:    uses.  Drives very near the boundaries may not be handled correctly (i.e.
                   2170:    near 2.0 Gb and 4.0 Gb) */
                   2171: 
                   2172:    if (iinfo[2] > 1024) {
                   2173:       iinfo[0] = 64;
                   2174:       iinfo[1] = 63;
                   2175:       iinfo[2] = disk->capacity / (iinfo[0] * iinfo[1]);
                   2176:       }
                   2177:    if (iinfo[2] > 1024) {
                   2178:       iinfo[0] = 128;
                   2179:       iinfo[1] = 63;
                   2180:       iinfo[2] = disk->capacity / (iinfo[0] * iinfo[1]);
                   2181:       }
                   2182:    if (iinfo[2] > 1024) {
                   2183:       iinfo[0] = 255;
                   2184:       iinfo[1] = 63;
                   2185:       iinfo[2] = disk->capacity / (iinfo[0] * iinfo[1]);
                   2186:       }
                   2187:     return 0;
                   2188: }
                   2189: 
                   2190: 
                   2191: 
                   2192: struct proc_dir_entry proc_scsi_in2000 = {
                   2193:    PROC_SCSI_IN2000, 6, "in2000",
                   2194:    S_IFDIR | S_IRUGO | S_IXUGO, 2
                   2195:    };
                   2196: 
                   2197: 
                   2198: int in2000_proc_info(char *buf, char **start, off_t off, int len, int hn, int in)
                   2199: {
                   2200: 
                   2201: #ifdef PROC_INTERFACE
                   2202: 
                   2203: char *bp;
                   2204: char tbuf[128];
                   2205: unsigned long flags;
                   2206: struct Scsi_Host *instance;
                   2207: struct IN2000_hostdata *hd;
                   2208: Scsi_Cmnd *cmd;
                   2209: int x,i;
                   2210: static int stop = 0;
                   2211: 
                   2212:    for (instance=instance_list; instance; instance=instance->next) {
                   2213:       if (instance->host_no == hn)
                   2214:          break;
                   2215:       }
                   2216:    if (!instance) {
                   2217:       printk("*** Hmm... Can't find host #%d!\n",hn);
                   2218:       return (-ESRCH);
                   2219:       }
                   2220:    hd = (struct IN2000_hostdata *)instance->hostdata;
                   2221: 
                   2222: /* If 'in' is TRUE we need to _read_ the proc file. We accept the following
                   2223:  * keywords (same format as command-line, but only ONE per read):
                   2224:  *    debug
                   2225:  *    disconnect
                   2226:  *    period
                   2227:  *    resync
                   2228:  *    proc
                   2229:  */
                   2230: 
                   2231:    if (in) {
                   2232:       buf[len] = '\0';
                   2233:       bp = buf;
                   2234:       if (!strncmp(bp,"debug:",6)) {
                   2235:          bp += 6;
                   2236:          hd->args = simple_strtoul(bp,NULL,0) & DB_MASK;
                   2237:          }
                   2238:       else if (!strncmp(bp,"disconnect:",11)) {
                   2239:          bp += 11;
                   2240:          x = simple_strtoul(bp,NULL,0);
                   2241:          if (x < DIS_NEVER || x > DIS_ALWAYS)
                   2242:             x = DIS_ADAPTIVE;
                   2243:          hd->disconnect = x;
                   2244:          }
                   2245:       else if (!strncmp(bp,"period:",7)) {
                   2246:          bp += 7;
                   2247:          x = simple_strtoul(bp,NULL,0);
                   2248:          hd->default_sx_per = sx_table[round_period((unsigned int)x)].period_ns;
                   2249:          }
                   2250:       else if (!strncmp(bp,"resync:",7)) {
                   2251:          bp += 7;
                   2252:          x = simple_strtoul(bp,NULL,0);
                   2253:          for (i=0; i<7; i++)
                   2254:             if (x & (1<<i))
                   2255:                hd->sync_stat[i] = SS_UNSET;
                   2256:          }
                   2257:       else if (!strncmp(bp,"proc:",5)) {
                   2258:          bp += 5;
                   2259:          hd->proc = simple_strtoul(bp,NULL,0);
                   2260:          }
                   2261:       else if (!strncmp(bp,"level2:",7)) {
                   2262:          bp += 7;
                   2263:          hd->level2 = simple_strtoul(bp,NULL,0);
                   2264:          }
                   2265:       return len;
                   2266:       }
                   2267: 
                   2268:    save_flags(flags);
                   2269:    cli();
                   2270:    bp = buf;
                   2271:    *bp = '\0';
                   2272:    if (hd->proc & PR_VERSION) {
                   2273:       sprintf(tbuf,"\nVersion %s - %s. Compiled %s %s",
                   2274:             IN2000_VERSION,IN2000_DATE,__DATE__,__TIME__);
                   2275:       strcat(bp,tbuf);
                   2276:       }
                   2277:    if (hd->proc & PR_INFO) {
                   2278:       sprintf(tbuf,"\ndip_switch=%02x: irq=%d io=%02x floppy=%s sync/DOS5=%s",
                   2279:                   (hd->dip_switch & 0x7f), instance->irq, hd->io_base,
                   2280:                   (hd->dip_switch & 0x40)?"Yes":"No",
                   2281:                   (hd->dip_switch & 0x20)?"Yes":"No");
                   2282:       strcat(bp,tbuf);
                   2283:       strcat(bp,"\nsync_xfer[] =       ");
                   2284:       for (x=0; x<7; x++) {
                   2285:          sprintf(tbuf,"\t%02x",hd->sync_xfer[x]);
                   2286:          strcat(bp,tbuf);
                   2287:          }
                   2288:       strcat(bp,"\nsync_stat[] =       ");
                   2289:       for (x=0; x<7; x++) {
                   2290:          sprintf(tbuf,"\t%02x",hd->sync_stat[x]);
                   2291:          strcat(bp,tbuf);
                   2292:          }
                   2293:       }
                   2294: #ifdef PROC_STATISTICS
                   2295:    if (hd->proc & PR_STATISTICS) {
                   2296:       strcat(bp,"\ncommands issued:    ");
                   2297:       for (x=0; x<7; x++) {
                   2298:          sprintf(tbuf,"\t%ld",hd->cmd_cnt[x]);
                   2299:          strcat(bp,tbuf);
                   2300:          }
                   2301:       strcat(bp,"\ndisconnects allowed:");
                   2302:       for (x=0; x<7; x++) {
                   2303:          sprintf(tbuf,"\t%ld",hd->disc_allowed_cnt[x]);
                   2304:          strcat(bp,tbuf);
                   2305:          }
                   2306:       strcat(bp,"\ndisconnects done:   ");
                   2307:       for (x=0; x<7; x++) {
                   2308:          sprintf(tbuf,"\t%ld",hd->disc_done_cnt[x]);
                   2309:          strcat(bp,tbuf);
                   2310:          }
                   2311:       sprintf(tbuf,"\ninterrupts:      \t%ld",hd->int_cnt);
                   2312:       strcat(bp,tbuf);
                   2313:       }
                   2314: #endif
                   2315:    if (hd->proc & PR_CONNECTED) {
                   2316:       strcat(bp,"\nconnected:     ");
                   2317:       if (hd->connected) {
                   2318:          cmd = (Scsi_Cmnd *)hd->connected;
                   2319:          sprintf(tbuf," %ld-%d:%d(%02x)",
                   2320:                cmd->pid, cmd->target, cmd->lun, cmd->cmnd[0]);
                   2321:          strcat(bp,tbuf);
                   2322:          }
                   2323:       }
                   2324:    if (hd->proc & PR_INPUTQ) {
                   2325:       strcat(bp,"\ninput_Q:       ");
                   2326:       cmd = (Scsi_Cmnd *)hd->input_Q;
                   2327:       while (cmd) {
                   2328:          sprintf(tbuf," %ld-%d:%d(%02x)",
                   2329:                cmd->pid, cmd->target, cmd->lun, cmd->cmnd[0]);
                   2330:          strcat(bp,tbuf);
                   2331:          cmd = (Scsi_Cmnd *)cmd->host_scribble;
                   2332:          }
                   2333:       }
                   2334:    if (hd->proc & PR_DISCQ) {
                   2335:       strcat(bp,"\ndisconnected_Q:");
                   2336:       cmd = (Scsi_Cmnd *)hd->disconnected_Q;
                   2337:       while (cmd) {
                   2338:          sprintf(tbuf," %ld-%d:%d(%02x)",
                   2339:                cmd->pid, cmd->target, cmd->lun, cmd->cmnd[0]);
                   2340:          strcat(bp,tbuf);
                   2341:          cmd = (Scsi_Cmnd *)cmd->host_scribble;
                   2342:          }
                   2343:       }
                   2344:    if (hd->proc & PR_TEST) {
                   2345:       ;  /* insert your own custom function here */
                   2346:       }
                   2347:    strcat(bp,"\n");
                   2348:    restore_flags(flags);
                   2349:    *start = buf;
                   2350:    if (stop) {
                   2351:       stop = 0;
                   2352:       return 0;         /* return 0 to signal end-of-file */
                   2353:       }
                   2354:    if (off > 0x40000)   /* ALWAYS stop after 256k bytes have been read */
                   2355:       stop = 1;;
                   2356:    if (hd->proc & PR_STOP)    /* stop every other time */
                   2357:       stop = 1;
                   2358:    return strlen(bp);
                   2359: 
                   2360: #else    /* PROC_INTERFACE */
                   2361: 
                   2362:    return 0;
                   2363: 
                   2364: #endif   /* PROC_INTERFACE */
                   2365: 
                   2366: }
                   2367: 
                   2368: 
                   2369: #ifdef MODULE
                   2370: 
                   2371: Scsi_Host_Template driver_template = IN2000;
                   2372: 
                   2373: #include "scsi_module.c"
                   2374: 
                   2375: #endif
                   2376: 

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.