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