File: /usr/src/linux/drivers/scsi/wd33c93.c

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