OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [rc203soc/] [sw/] [uClinux/] [drivers/] [scsi/] [in2000.c] - Blame information for rev 1626

Go to most recent revision | Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.