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