root/drivers/scsi/in2000.c

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

DEFINITIONS

This source file includes following definitions.
  1. read_3393
  2. write_3393
  3. write_3393_cmd
  4. read_1_byte
  5. write_3393_count
  6. read_3393_count
  7. round_period
  8. calc_sync_xfer
  9. in2000_queuecommand
  10. in2000_execute
  11. transfer_pio
  12. transfer_bytes
  13. in2000_intr
  14. reset_hardware
  15. in2000_reset
  16. in2000_abort
  17. in2000_setup
  18. check_setup_strings
  19. in2000_detect
  20. in2000_biosparam
  21. in2000_proc_info

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

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