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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [linux/] [linux-2.4/] [drivers/] [scsi/] [wd33c93.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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