File: /usr/src/linux/drivers/acorn/scsi/fas216.c

1     /*
2      *  linux/arch/arm/drivers/scsi/fas216.c
3      *
4      *  Copyright (C) 1997-2000 Russell King
5      *
6      * This program is free software; you can redistribute it and/or modify
7      * it under the terms of the GNU General Public License version 2 as
8      * published by the Free Software Foundation.
9      *
10      * Based on information in qlogicfas.c by Tom Zerucha, Michael Griffith, and
11      * other sources, including:
12      *   the AMD Am53CF94 data sheet
13      *   the AMD Am53C94 data sheet 
14      *
15      * This is a generic driver.  To use it, have a look at cumana_2.c.  You
16      * should define your own structure that overlays FAS216_Info, eg:
17      * struct my_host_data {
18      *    FAS216_Info info;
19      *    ... my host specific data ...
20      * };
21      *
22      * Changelog:
23      *  30-08-1997	RMK	Created
24      *  14-09-1997	RMK	Started disconnect support
25      *  08-02-1998	RMK	Corrected real DMA support
26      *  15-02-1998	RMK	Started sync xfer support
27      *  06-04-1998	RMK	Tightened conditions for printing incomplete
28      *			transfers
29      *  02-05-1998	RMK	Added extra checks in fas216_reset
30      *  24-05-1998	RMK	Fixed synchronous transfers with period >= 200ns
31      *  27-06-1998	RMK	Changed asm/delay.h to linux/delay.h
32      *  26-08-1998	RMK	Improved message support wrt MESSAGE_REJECT
33      *  02-04-2000	RMK	Converted to use the new error handling, and
34      *			automatically request sense data upon check
35      *			condition status from targets.
36      *
37      * Todo:
38      *  - allow individual devices to enable sync xfers.
39      */
40     #include <linux/module.h>
41     #include <linux/blk.h>
42     #include <linux/kernel.h>
43     #include <linux/string.h>
44     #include <linux/ioport.h>
45     #include <linux/sched.h>
46     #include <linux/proc_fs.h>
47     #include <linux/unistd.h>
48     #include <linux/stat.h>
49     #include <linux/delay.h>
50     #include <linux/init.h>
51     
52     #include <asm/dma.h>
53     #include <asm/io.h>
54     #include <asm/irq.h>
55     #include <asm/ecard.h>
56     
57     #define FAS216_C
58     
59     #include "../../scsi/scsi.h"
60     #include "../../scsi/hosts.h"
61     #include "fas216.h"
62     
63     MODULE_AUTHOR("Russell King");
64     MODULE_DESCRIPTION("Generic FAS216/NCR53C9x driver");
65     
66     #define VER_MAJOR	0
67     #define VER_MINOR	0
68     #define VER_PATCH	5
69     
70     /* NOTE: SCSI2 Synchronous transfers *require* DMA according to
71      *  the data sheet.  This restriction is crazy, especially when
72      *  you only want to send 16 bytes!  What were the guys who
73      *  designed this chip on at that time?  Did they read the SCSI2
74      *  spec at all?  The following sections are taken from the SCSI2
75      *  standard (s2r10) concerning this:
76      *
77      * > IMPLEMENTORS NOTES:
78      * >   (1)  Re-negotiation at every selection is not recommended, since a
79      * >   significant performance impact is likely.
80      *
81      * >  The implied synchronous agreement shall remain in effect until a BUS DEVICE
82      * >  RESET message is received, until a hard reset condition occurs, or until one
83      * >  of the two SCSI devices elects to modify the agreement.  The default data
84      * >  transfer mode is asynchronous data transfer mode.  The default data transfer
85      * >  mode is entered at power on, after a BUS DEVICE RESET message, or after a hard
86      * >  reset condition.
87      *
88      *  In total, this means that once you have elected to use synchronous
89      *  transfers, you must always use DMA.
90      *
91      *  I was thinking that this was a good chip until I found this restriction ;(
92      */
93     #define SCSI2_SYNC
94     #undef  SCSI2_WIDE
95     #undef  SCSI2_TAG
96     
97     #undef DEBUG_CONNECT
98     #undef DEBUG_BUSSERVICE
99     #undef DEBUG_FUNCTIONDONE
100     #undef DEBUG_MESSAGES
101     
102     #undef CHECK_STRUCTURE
103     
104     static struct { int stat, ssr, isr, ph; } list[8];
105     static int ptr;
106     
107     static void fas216_dumpstate(FAS216_Info *info)
108     {
109     	unsigned char is, stat, inst;
110     
111     	is   = inb(REG_IS(info));
112     	stat = inb(REG_STAT(info));
113     	inst = inb(REG_INST(info));
114     	
115     	printk("FAS216: CTCL=%02X CTCM=%02X CMD=%02X STAT=%02X"
116     	       " INST=%02X IS=%02X CFIS=%02X",
117     		inb(REG_CTCL(info)), inb(REG_CTCM(info)),
118     		inb(REG_CMD(info)),  stat, inst, is,
119     		inb(REG_CFIS(info)));
120     	printk(" CNTL1=%02X CNTL2=%02X CNTL3=%02X CTCH=%02X\n",
121     		inb(REG_CNTL1(info)), inb(REG_CNTL2(info)),
122     		inb(REG_CNTL3(info)), inb(REG_CTCH(info)));
123     }
124     
125     static void fas216_dumpinfo(FAS216_Info *info)
126     {
127     	static int used = 0;
128     	int i;
129     
130     	if (used++)
131     		return;
132     
133     	printk("FAS216_Info=\n");
134     	printk("  { magic_start=%lX host=%p SCpnt=%p origSCpnt=%p\n",
135     		info->magic_start, info->host, info->SCpnt,
136     		info->origSCpnt);
137     	printk("    scsi={ io_port=%X io_shift=%X irq=%X cfg={ %X %X %X %X }\n",
138     		info->scsi.io_port, info->scsi.io_shift, info->scsi.irq,
139     		info->scsi.cfg[0], info->scsi.cfg[1], info->scsi.cfg[2],
140     		info->scsi.cfg[3]);
141     	printk("           type=%p phase=%X reconnected={ target=%d lun=%d tag=%d }\n",
142     		info->scsi.type, info->scsi.phase,
143     		info->scsi.reconnected.target,
144     		info->scsi.reconnected.lun, info->scsi.reconnected.tag);
145     	printk("           SCp={ ptr=%p this_residual=%X buffer=%p buffers_residual=%X }\n",
146     		info->scsi.SCp.ptr, info->scsi.SCp.this_residual,
147     		info->scsi.SCp.buffer, info->scsi.SCp.buffers_residual);
148     	printk("      msgs async_stp=%X disconnectable=%d aborting=%d }\n",
149     		info->scsi.async_stp,
150     		info->scsi.disconnectable, info->scsi.aborting);
151     	printk("    stats={ queues=%X removes=%X fins=%X reads=%X writes=%X miscs=%X\n"
152     	       "            disconnects=%X aborts=%X bus_resets=%X host_resets=%X}\n",
153     		info->stats.queues, info->stats.removes, info->stats.fins,
154     		info->stats.reads, info->stats.writes, info->stats.miscs,
155     		info->stats.disconnects, info->stats.aborts, info->stats.bus_resets,
156     		info->stats.host_resets);
157     	printk("    ifcfg={ clockrate=%X select_timeout=%X asyncperiod=%X sync_max_depth=%X }\n",
158     		info->ifcfg.clockrate, info->ifcfg.select_timeout,
159     		info->ifcfg.asyncperiod, info->ifcfg.sync_max_depth);
160     	for (i = 0; i < 8; i++) {
161     		printk("    busyluns[%d]=%X dev[%d]={ disconnect_ok=%d stp=%X sof=%X sync_state=%X }\n",
162     			i, info->busyluns[i], i,
163     			info->device[i].disconnect_ok, info->device[i].stp,
164     			info->device[i].sof, info->device[i].sync_state);
165     	}
166     	printk("    dma={ transfer_type=%X setup=%p pseudo=%p stop=%p }\n",
167     		info->dma.transfer_type, info->dma.setup,
168     		info->dma.pseudo, info->dma.stop);
169     	printk("    internal_done=%X magic_end=%lX }\n",
170     		info->internal_done, info->magic_end);
171     }
172     
173     #ifdef CHECK_STRUCTURE
174     static void __fas216_checkmagic(FAS216_Info *info, const char *func)
175     {
176     	int corruption = 0;
177     	if (info->magic_start != MAGIC) {
178     		printk(KERN_CRIT "FAS216 Error: magic at start corrupted\n");
179     		corruption++;
180     	}
181     	if (info->magic_end != MAGIC) {
182     		printk(KERN_CRIT "FAS216 Error: magic at end corrupted\n");
183     		corruption++;
184     	}
185     	if (corruption) {
186     		fas216_dumpinfo(info);
187     		panic("scsi memory space corrupted in %s", func);
188     	}
189     }
190     #define fas216_checkmagic(info) __fas216_checkmagic((info), __FUNCTION__)
191     #else
192     #define fas216_checkmagic(info)
193     #endif
194     
195     static const char *fas216_bus_phase(int stat)
196     {
197     	static const char *phases[] = {
198     		"DATA OUT", "DATA IN",
199     		"COMMAND", "STATUS",
200     		"MISC OUT", "MISC IN",
201     		"MESG OUT", "MESG IN"
202     	};
203     
204     	return phases[stat & STAT_BUSMASK];
205     }
206     
207     static const char *fas216_drv_phase(FAS216_Info *info)
208     {
209     	switch (info->scsi.phase) {
210     	case PHASE_IDLE:		return "idle";
211     	case PHASE_SELECTION:		return "selection";
212     	case PHASE_COMMAND:		return "command";
213     	case PHASE_RECONNECTED:		return "reconnected";
214     	case PHASE_DATAOUT:		return "data out";
215     	case PHASE_DATAIN:		return "data in";
216     	case PHASE_MSGIN:		return "message in";
217     	case PHASE_MSGIN_DISCONNECT:	return "disconnect";
218     	case PHASE_MSGOUT_EXPECT:	return "expect message out";
219     	case PHASE_MSGOUT:		return "message out";
220     	case PHASE_STATUS:		return "status";
221     	case PHASE_DONE:		return "done";
222     	default:			return "???";
223     	}
224     }
225     
226     static char fas216_target(FAS216_Info *info)
227     {
228     	if (info->SCpnt)
229     		return '0' + info->SCpnt->target;
230     	else
231     		return 'H';
232     }
233     
234     static void add_debug_list(int stat, int ssr, int isr, int ph)
235     {
236     	list[ptr].stat = stat;
237     	list[ptr].ssr = ssr;
238     	list[ptr].isr = isr;
239     	list[ptr].ph = ph;
240     
241     	ptr = (ptr + 1) & 7;
242     }
243     
244     static void print_debug_list(void)
245     {
246     	int i;
247     
248     	i = ptr;
249     
250     	printk(KERN_ERR "SCSI IRQ trail: ");
251     	do {
252     		printk("%02X:%02X:%02X:%1X ",
253     			list[i].stat, list[i].ssr,
254     			list[i].isr, list[i].ph);
255     		i = (i + 1) & 7;
256     	} while (i != ptr);
257     	printk("\n");
258     }
259     
260     static void fas216_done(FAS216_Info *info, unsigned int result);
261     
262     /* Function: int fas216_clockrate(unsigned int clock)
263      * Purpose : calculate correct value to be written into clock conversion
264      *	     factor register.
265      * Params  : clock - clock speed in MHz
266      * Returns : CLKF_ value
267      */
268     static int fas216_clockrate(int clock)
269     {
270     	if (clock <= 10 || clock > 40) {
271     		printk(KERN_CRIT
272     		       "fas216: invalid clock rate: check your driver!\n");
273     		clock = -1;
274     	} else
275     		clock = ((clock - 1) / 5 + 1) & 7;
276     
277     	return clock;
278     }
279     
280     /* Function: unsigned short fas216_get_last_msg(FAS216_Info *info, int pos)
281      * Purpose : retrieve a last message from the list, using position in fifo
282      * Params  : info - interface to search
283      *         : pos  - current fifo position
284      */
285     static inline unsigned short
286     fas216_get_last_msg(FAS216_Info *info, int pos)
287     {
288     	unsigned short packed_msg = NOP;
289     	struct message *msg;
290     	int msgnr = 0;
291     
292     	while ((msg = msgqueue_getmsg(&info->scsi.msgs, msgnr++)) != NULL) {
293     		if (pos >= msg->fifo)
294     			break;
295     	}
296     
297     	if (msg) {
298     		if (msg->msg[0] == EXTENDED_MESSAGE)
299     			packed_msg = EXTENDED_MESSAGE | msg->msg[2] << 8;
300     		else
301     			packed_msg = msg->msg[0];
302     	}
303     
304     #ifdef DEBUG_MESSAGES
305     	printk("Message: %04X found at position %02X\n",
306     		packed_msg, pos);
307     #endif
308     	return packed_msg;
309     }
310     
311     /* Function: int fas216_syncperiod(FAS216_Info *info, int ns)
312      * Purpose : Calculate value to be loaded into the STP register
313      *           for a given period in ns
314      * Params  : info - state structure for interface connected to device
315      *         : ns   - period in ns (between subsequent bytes)
316      * Returns : Value suitable for REG_STP
317      */
318     static int
319     fas216_syncperiod(FAS216_Info *info, int ns)
320     {
321     	int value = (info->ifcfg.clockrate * ns) / 1000;
322     
323     	fas216_checkmagic(info);
324     
325     	if (value < 4)
326     		value = 4;
327     	else if (value > 35)
328     		value = 35;
329     
330     	return value & 31;
331     }
332     
333     /* Function: void fas216_set_sync(FAS216_Info *info, int target)
334      * Purpose : Correctly setup FAS216 chip for specified transfer period.
335      * Params  : info   - state structure for interface
336      *         : target - target
337      * Notes   : we need to switch the chip out of FASTSCSI mode if we have
338      *           a transfer period >= 200ns - otherwise the chip will violate
339      *           the SCSI timings.
340      */
341     static void
342     fas216_set_sync(FAS216_Info *info, int target)
343     {
344     	outb(info->device[target].sof, REG_SOF(info));
345     	outb(info->device[target].stp, REG_STP(info));
346     	if (info->device[target].period >= (200 / 4))
347     		outb(info->scsi.cfg[2] & ~CNTL3_FASTSCSI, REG_CNTL3(info));
348     	else
349     		outb(info->scsi.cfg[2], REG_CNTL3(info));
350     }
351     
352     /* Synchronous transfer support
353      *
354      * Note: The SCSI II r10 spec says (5.6.12):
355      *
356      *  (2)  Due to historical problems with early host adapters that could
357      *  not accept an SDTR message, some targets may not initiate synchronous
358      *  negotiation after a power cycle as required by this standard.  Host
359      *  adapters that support synchronous mode may avoid the ensuing failure
360      *  modes when the target is independently power cycled by initiating a
361      *  synchronous negotiation on each REQUEST SENSE and INQUIRY command.
362      *  This approach increases the SCSI bus overhead and is not recommended
363      *  for new implementations.  The correct method is to respond to an
364      *  SDTR message with a MESSAGE REJECT message if the either the
365      *  initiator or target devices does not support synchronous transfers
366      *  or does not want to negotiate for synchronous transfers at the time.
367      *  Using the correct method assures compatibility with wide data
368      *  transfers and future enhancements.
369      *
370      * We will always initiate a synchronous transfer negociation request on
371      * every INQUIRY or REQUEST SENSE message, unless the target itself has
372      * at some point performed a synchronous transfer negociation request, or
373      * we have synchronous transfers disabled for this device.
374      */
375     
376     /* Function: void fas216_handlesync(FAS216_Info *info, char *msg)
377      * Purpose : Handle a synchronous transfer message from the target
378      * Params  : info - state structure for interface
379      *         : msg  - message from target
380      */
381     static void
382     fas216_handlesync(FAS216_Info *info, char *msg)
383     {
384     	struct fas216_device *dev = &info->device[info->SCpnt->target];
385     	enum { sync, async, none, reject } res = none;
386     
387     #ifdef SCSI2_SYNC
388     	switch (msg[0]) {
389     	case MESSAGE_REJECT:
390     		/* Synchronous transfer request failed.
391     		 * Note: SCSI II r10:
392     		 *
393     		 *  SCSI devices that are capable of synchronous
394     		 *  data transfers shall not respond to an SDTR
395     		 *  message with a MESSAGE REJECT message.
396     		 *
397     		 * Hence, if we get this condition, we disable
398     		 * negociation for this device.
399     		 */
400     		if (dev->sync_state == neg_inprogress) {
401     			dev->sync_state = neg_invalid;
402     			res = async;
403     		}
404     		break;
405     
406     	case EXTENDED_MESSAGE:
407     		switch (dev->sync_state) {
408     		/* We don't accept synchronous transfer requests.
409     		 * Respond with a MESSAGE_REJECT to prevent a
410     		 * synchronous transfer agreement from being reached.
411     		 */
412     		case neg_invalid:
413     			res = reject;
414     			break;
415     
416     		/* We were not negociating a synchronous transfer,
417     		 * but the device sent us a negociation request.
418     		 * Honour the request by sending back a SDTR
419     		 * message containing our capability, limited by
420     		 * the targets capability.
421     		 */
422     		default:
423     			outb(CMD_SETATN, REG_CMD(info));
424     			if (msg[4] > info->ifcfg.sync_max_depth)
425     				msg[4] = info->ifcfg.sync_max_depth;
426     			if (msg[3] < 1000 / info->ifcfg.clockrate)
427     				msg[3] = 1000 / info->ifcfg.clockrate;
428     
429     			msgqueue_flush(&info->scsi.msgs);
430     			msgqueue_addmsg(&info->scsi.msgs, 5,
431     					EXTENDED_MESSAGE, 3, EXTENDED_SDTR,
432     					msg[3], msg[4]);
433     			info->scsi.phase = PHASE_MSGOUT_EXPECT;
434     
435     			/* This is wrong.  The agreement is not in effect
436     			 * until this message is accepted by the device
437     			 */
438     			dev->sync_state = neg_targcomplete;
439     			res = sync;
440     			break;
441     
442     		/* We initiated the synchronous transfer negociation,
443     		 * and have successfully received a response from the
444     		 * target.  The synchronous transfer agreement has been
445     		 * reached.  Note: if the values returned are out of our
446     		 * bounds, we must reject the message.
447     		 */
448     		case neg_inprogress:
449     			res = reject;
450     			if (msg[4] <= info->ifcfg.sync_max_depth &&
451     			    msg[3] >= 1000 / info->ifcfg.clockrate) {
452     				dev->sync_state = neg_complete;
453     				res = sync;
454     			}
455     			break;
456     		}
457     	}
458     #else
459     	res = reject;
460     #endif
461     
462     	switch (res) {
463     	case sync:
464     		dev->period = msg[3];
465     		dev->sof    = msg[4];
466     		dev->stp    = fas216_syncperiod(info, msg[3] * 4);
467     		fas216_set_sync(info, info->SCpnt->target);
468     		break;
469     
470     	case reject:
471     		outb(CMD_SETATN, REG_CMD(info));
472     		msgqueue_flush(&info->scsi.msgs);
473     		msgqueue_addmsg(&info->scsi.msgs, 1, MESSAGE_REJECT);
474     		info->scsi.phase = PHASE_MSGOUT_EXPECT;
475     
476     	case async:
477     		dev->period = info->ifcfg.asyncperiod / 4;
478     		dev->sof    = 0;
479     		dev->stp    = info->scsi.async_stp;
480     		fas216_set_sync(info, info->SCpnt->target);
481     		break;
482     
483     	case none:
484     		break;
485     	}
486     }
487     
488     /* Function: void fas216_handlewide(FAS216_Info *info, char *msg)
489      * Purpose : Handle a wide transfer message from the target
490      * Params  : info - state structure for interface
491      *         : msg  - message from target
492      */
493     static void
494     fas216_handlewide(FAS216_Info *info, char *msg)
495     {
496     	struct fas216_device *dev = &info->device[info->SCpnt->target];
497     	enum { wide, bit8, none, reject } res = none;
498     
499     #ifdef SCSI2_WIDE
500     	switch (msg[0]) {
501     	case MESSAGE_REJECT:
502     		/* Wide transfer request failed.
503     		 * Note: SCSI II r10:
504     		 *
505     		 *  SCSI devices that are capable of wide
506     		 *  data transfers shall not respond to a
507     		 *  WDTR message with a MESSAGE REJECT message.
508     		 *
509     		 * Hence, if we get this condition, we never
510     		 * reattempt negociation for this device.
511     		 */
512     		if (dev->wide_state == neg_inprogress) {
513     			dev->wide_state = neg_invalid;
514     			res = bit8;
515     		}
516     		break;
517     
518     	case EXTENDED_MESSAGE:
519     		switch (dev->wide_state) {
520     		/* We don't accept wide data transfer requests.
521     		 * Respond with a MESSAGE REJECT to prevent a
522     		 * wide data transfer agreement from being reached.
523     		 */
524     		case neg_invalid:
525     			res = reject;
526     			break;
527     
528     		/* We were not negociating a wide data transfer,
529     		 * but the device sent is a negociation request.
530     		 * Honour the request by sending back a WDTR
531     		 * message containing our capability, limited by
532     		 * the targets capability.
533     		 */
534     		default:
535     			outb(CMD_SETATN, REG_CMD(info));
536     			if (msg[3] > info->ifcfg.wide_max_size)
537     				msg[3] = info->ifcfg.wide_max_size;
538     
539     			msgqueue_flush(&info->scsi.msgs);
540     			msgqueue_addmsg(&info->scsi.msgs, 4,
541     					EXTENDED_MESSAGE, 2, EXTENDED_WDTR,
542     					msg[3]);
543     			info->scsi.phase = PHASE_MSGOUT_EXPECT;
544     			res = wide;
545     			break;
546     
547     		/* We initiated the wide data transfer negociation,
548     		 * and have successfully received a response from the
549     		 * target.  The synchronous transfer agreement has been
550     		 * reached.  Note: if the values returned are out of our
551     		 * bounds, we must reject the message.
552     		 */
553     		case neg_inprogress:
554     			res = reject;
555     			if (msg[3] <= info->ifcfg.wide_max_size) {
556     				dev->wide_state = neg_complete;
557     				res = wide;
558     			}
559     			break;
560     		}
561     	}
562     #else
563     	res = reject;
564     #endif
565     
566     	switch (res) {
567     	case wide:
568     		dev->wide_xfer = msg[3];
569     		break;
570     
571     	case reject:
572     		outb(CMD_SETATN, REG_CMD(info));
573     		msgqueue_flush(&info->scsi.msgs);
574     		msgqueue_addmsg(&info->scsi.msgs, 1, MESSAGE_REJECT);
575     		info->scsi.phase = PHASE_MSGOUT_EXPECT;
576     
577     	case bit8:
578     		dev->wide_xfer = 0;
579     		break;
580     
581     	case none:
582     		break;
583     	}
584     }
585     
586     /* Function: void fas216_updateptrs(FAS216_Info *info, int bytes_transferred)
587      * Purpose : update data pointers after transfer suspended/paused
588      * Params  : info              - interface's local pointer to update
589      *           bytes_transferred - number of bytes transferred
590      */
591     static void
592     fas216_updateptrs(FAS216_Info *info, int bytes_transferred)
593     {
594     	unsigned char *ptr;
595     	unsigned int residual;
596     
597     	fas216_checkmagic(info);
598     
599     	ptr = info->scsi.SCp.ptr;
600     	residual = info->scsi.SCp.this_residual;
601     
602     	info->SCpnt->request_bufflen -= bytes_transferred;
603     
604     	while (residual <= bytes_transferred && bytes_transferred) {
605     		/* We have used up this buffer */
606     		bytes_transferred -= residual;
607     		if (info->scsi.SCp.buffers_residual) {
608     			info->scsi.SCp.buffer++;
609     			info->scsi.SCp.buffers_residual--;
610     			ptr = (unsigned char *)info->scsi.SCp.buffer->address;
611     			residual = info->scsi.SCp.buffer->length;
612     		} else {
613     			ptr = NULL;
614     			residual = 0;
615     		}
616     	}
617     
618     	residual -= bytes_transferred;
619     	ptr += bytes_transferred;
620     
621     	if (residual == 0)
622     		ptr = NULL;
623     
624     	info->scsi.SCp.ptr = ptr;
625     	info->scsi.SCp.this_residual = residual;
626     }
627     
628     /* Function: void fas216_pio(FAS216_Info *info, fasdmadir_t direction)
629      * Purpose : transfer data off of/on to card using programmed IO
630      * Params  : info      - interface to transfer data to/from
631      *           direction - direction to transfer data (DMA_OUT/DMA_IN)
632      * Notes   : this is incredibly slow
633      */
634     static void
635     fas216_pio(FAS216_Info *info, fasdmadir_t direction)
636     {
637     	unsigned int residual;
638     	char *ptr;
639     
640     	fas216_checkmagic(info);
641     
642     	residual = info->scsi.SCp.this_residual;
643     	ptr = info->scsi.SCp.ptr;
644     
645     	if (direction == DMA_OUT)
646     		outb(*ptr++, REG_FF(info));
647     	else
648     		*ptr++ = inb(REG_FF(info));
649     
650     	residual -= 1;
651     
652     	if (residual == 0) {
653     		if (info->scsi.SCp.buffers_residual) {
654     			info->scsi.SCp.buffer++;
655     			info->scsi.SCp.buffers_residual--;
656     			ptr = (unsigned char *)info->scsi.SCp.buffer->address;
657     			residual = info->scsi.SCp.buffer->length;
658     		} else {
659     			ptr = NULL;
660     			residual = 0;
661     		}
662     	}
663     
664     	info->scsi.SCp.ptr = ptr;
665     	info->scsi.SCp.this_residual = residual;
666     }
667     
668     /* Function: void fas216_starttransfer(FAS216_Info *info,
669      *				       fasdmadir_t direction)
670      * Purpose : Start a DMA/PIO transfer off of/on to card
671      * Params  : info      - interface from which device disconnected from
672      *           direction - transfer direction (DMA_OUT/DMA_IN)
673      */
674     static void
675     fas216_starttransfer(FAS216_Info *info, fasdmadir_t direction, int flush_fifo)
676     {
677     	fasdmatype_t dmatype;
678     
679     	fas216_checkmagic(info);
680     
681     	info->scsi.phase = (direction == DMA_OUT) ?
682     				PHASE_DATAOUT : PHASE_DATAIN;
683     
684     	if (info->dma.transfer_type != fasdma_none &&
685     	    info->dma.transfer_type != fasdma_pio) {
686     		unsigned long total, residual;
687     
688     		if (info->dma.transfer_type == fasdma_real_all)
689     			total = info->SCpnt->request_bufflen;
690     		else
691     			total = info->scsi.SCp.this_residual;
692     
693     		residual = (inb(REG_CFIS(info)) & CFIS_CF) +
694     			    inb(REG_CTCL(info)) +
695     			    (inb(REG_CTCM(info)) << 8) +
696     			    (inb(REG_CTCH(info)) << 16);
697     		fas216_updateptrs(info, total - residual);
698     	}
699     	info->dma.transfer_type = fasdma_none;
700     
701     	if (!info->scsi.SCp.ptr) {
702     		printk("scsi%d.%c: null buffer passed to "
703     			"fas216_starttransfer\n", info->host->host_no,
704     			fas216_target(info));
705     		return;
706     	}
707     
708     	/* flush FIFO */
709     	if (flush_fifo)
710     		outb(CMD_FLUSHFIFO, REG_CMD(info));
711     
712     	/*
713     	 * Default to PIO mode or DMA mode if we have a synchronous
714     	 * transfer agreement.
715     	 */
716     	if (info->device[info->SCpnt->target].sof && info->dma.setup)
717     		dmatype = fasdma_real_all;
718     	else
719     		dmatype = fasdma_pio;
720     
721     	if (info->dma.setup)
722     		dmatype = info->dma.setup(info->host, &info->scsi.SCp,
723     					  direction, dmatype);
724     	info->dma.transfer_type = dmatype;
725     
726     	switch (dmatype) {
727     	case fasdma_pio:
728     		outb(0, REG_SOF(info));
729     		outb(info->scsi.async_stp, REG_STP(info));
730     		outb(info->scsi.SCp.this_residual, REG_STCL(info));
731     		outb(info->scsi.SCp.this_residual >> 8, REG_STCM(info));
732     		outb(info->scsi.SCp.this_residual >> 16, REG_STCH(info));
733     		outb(CMD_TRANSFERINFO, REG_CMD(info));
734     		fas216_pio(info, direction);
735     		break;
736     
737     	case fasdma_pseudo:
738     		outb(info->scsi.SCp.this_residual, REG_STCL(info));
739     		outb(info->scsi.SCp.this_residual >> 8, REG_STCM(info));
740     		outb(info->scsi.SCp.this_residual >> 16, REG_STCH(info));
741     		outb(CMD_TRANSFERINFO | CMD_WITHDMA, REG_CMD(info));
742     		info->dma.pseudo(info->host, &info->scsi.SCp,
743     				 direction, info->SCpnt->transfersize);
744     		break;
745     
746     	case fasdma_real_block:
747     		outb(info->scsi.SCp.this_residual, REG_STCL(info));
748     		outb(info->scsi.SCp.this_residual >> 8, REG_STCM(info));
749     		outb(info->scsi.SCp.this_residual >> 16, REG_STCH(info));
750     		outb(CMD_TRANSFERINFO | CMD_WITHDMA, REG_CMD(info));
751     		break;
752     
753     	case fasdma_real_all:
754     		outb(info->SCpnt->request_bufflen, REG_STCL(info));
755     		outb(info->SCpnt->request_bufflen >> 8, REG_STCM(info));
756     		outb(info->SCpnt->request_bufflen >> 16, REG_STCH(info));
757     		outb(CMD_TRANSFERINFO | CMD_WITHDMA, REG_CMD(info));
758     		break;
759     
760     	default:
761     		printk(KERN_ERR "scsi%d.%d: invalid FAS216 DMA type\n",
762     		       info->host->host_no, fas216_target(info));
763     		break;
764     	}
765     }
766     
767     /* Function: void fas216_stoptransfer(FAS216_Info *info)
768      * Purpose : Stop a DMA transfer onto / off of the card
769      * Params  : info      - interface from which device disconnected from
770      */
771     static void
772     fas216_stoptransfer(FAS216_Info *info)
773     {
774     	fas216_checkmagic(info);
775     
776     	if (info->dma.transfer_type != fasdma_none &&
777     	    info->dma.transfer_type != fasdma_pio) {
778     		unsigned long total, residual;
779     
780     		if ((info->dma.transfer_type == fasdma_real_all ||
781     		     info->dma.transfer_type == fasdma_real_block) &&
782     		    info->dma.stop)
783     			info->dma.stop(info->host, &info->scsi.SCp);
784     
785     		if (info->dma.transfer_type == fasdma_real_all)
786     			total = info->SCpnt->request_bufflen;
787     		else
788     			total = info->scsi.SCp.this_residual;
789     
790     		residual = (inb(REG_CFIS(info)) & CFIS_CF) +
791     			    inb(REG_CTCL(info)) +
792     			    (inb(REG_CTCM(info)) << 8) +
793     			    (inb(REG_CTCH(info)) << 16);
794     		fas216_updateptrs(info, total - residual);
795     		info->dma.transfer_type = fasdma_none;
796     	}
797     	if (info->scsi.phase == PHASE_DATAOUT)
798     		outb(CMD_FLUSHFIFO, REG_CMD(info));
799     }
800     
801     /* Function: void fas216_disconnected_intr(FAS216_Info *info)
802      * Purpose : handle device disconnection
803      * Params  : info - interface from which device disconnected from
804      */
805     static void
806     fas216_disconnect_intr(FAS216_Info *info)
807     {
808     	fas216_checkmagic(info);
809     
810     #ifdef DEBUG_CONNECT
811     	printk("scsi%d.%c: disconnect phase=%02X\n", info->host->host_no,
812     		fas216_target(info), info->scsi.phase);
813     #endif
814     	msgqueue_flush(&info->scsi.msgs);
815     
816     	switch (info->scsi.phase) {
817     	case PHASE_SELECTION:			/* while selecting - no target		*/
818     	case PHASE_SELSTEPS:
819     		fas216_done(info, DID_NO_CONNECT);
820     		break;
821     
822     	case PHASE_MSGIN_DISCONNECT:		/* message in - disconnecting		*/
823     		outb(CMD_ENABLESEL, REG_CMD(info));
824     		info->scsi.disconnectable = 1;
825     		info->scsi.reconnected.tag = 0;
826     		info->scsi.phase = PHASE_IDLE;
827     		info->stats.disconnects += 1;
828     		break;
829     
830     	case PHASE_DONE:			/* at end of command - complete		*/
831     		fas216_done(info, DID_OK);
832     		break;
833     
834     	case PHASE_MSGOUT:			/* message out - possible ABORT message	*/
835     		if (fas216_get_last_msg(info, info->scsi.msgin_fifo) == ABORT) {
836     			info->scsi.aborting = 0;
837     			fas216_done(info, DID_ABORT);
838     			break;
839     		}
840     
841     	default:				/* huh?					*/
842     		printk(KERN_ERR "scsi%d.%c: unexpected disconnect in phase %s\n",
843     			info->host->host_no, fas216_target(info), fas216_drv_phase(info));
844     		print_debug_list();
845     		fas216_stoptransfer(info);
846     		fas216_done(info, DID_ERROR);
847     		break;
848     	}
849     }
850     
851     /* Function: void fas216_reselected_intr(FAS216_Info *info)
852      * Purpose : Start reconnection of a device
853      * Params  : info - interface which was reselected
854      */
855     static void
856     fas216_reselected_intr(FAS216_Info *info)
857     {
858     	unsigned char target, identify_msg, ok;
859     
860     	fas216_checkmagic(info);
861     
862     	if ((info->scsi.phase == PHASE_SELECTION ||
863     	     info->scsi.phase == PHASE_SELSTEPS) && info->SCpnt) {
864     		Scsi_Cmnd *SCpnt = info->SCpnt;
865     
866     		info->origSCpnt = SCpnt;
867     		info->SCpnt = NULL;
868     
869     		if (info->device[SCpnt->target].wide_state == neg_inprogress)
870     			info->device[SCpnt->target].wide_state = neg_wait;
871     		if (info->device[SCpnt->target].sync_state == neg_inprogress)
872     			info->device[SCpnt->target].sync_state = neg_wait;
873     	}
874     
875     #ifdef DEBUG_CONNECT
876     	printk("scsi%d.%c: reconnect phase=%02X\n", info->host->host_no,
877     		fas216_target(info), info->scsi.phase);
878     #endif
879     
880     	if ((inb(REG_CFIS(info)) & CFIS_CF) != 2) {
881     		printk(KERN_ERR "scsi%d.H: incorrect number of bytes after reselect\n",
882     			info->host->host_no);
883     		outb(CMD_SETATN, REG_CMD(info));
884     		outb(CMD_MSGACCEPTED, REG_CMD(info));
885     		msgqueue_flush(&info->scsi.msgs);
886     		msgqueue_addmsg(&info->scsi.msgs, 1, INITIATOR_ERROR);
887     		info->scsi.phase = PHASE_MSGOUT_EXPECT;
888     		return;
889     	}
890     
891     	target = inb(REG_FF(info));
892     	identify_msg = inb(REG_FF(info));
893     
894     	ok = 1;
895     	if (!(target & (1 << info->host->this_id))) {
896     		printk(KERN_ERR "scsi%d.H: invalid host id on reselect\n", info->host->host_no);
897     		ok = 0;
898     	}
899     
900     	if (!(identify_msg & 0x80)) {
901     		printk(KERN_ERR "scsi%d.H: no IDENTIFY message on reselect, got msg %02X\n",
902     			info->host->host_no, identify_msg);
903     		ok = 0;
904     	}
905     
906     	if (!ok) {
907     		/*
908     		 * Something went wrong - send an initiator error to
909     		 * the target.
910     		 */
911     		outb(CMD_SETATN, REG_CMD(info));
912     		outb(CMD_MSGACCEPTED, REG_CMD(info));
913     		msgqueue_flush(&info->scsi.msgs);
914     		msgqueue_addmsg(&info->scsi.msgs, 1, INITIATOR_ERROR);
915     		info->scsi.phase = PHASE_MSGOUT_EXPECT;
916     		return;
917     	}
918     
919     	target &= ~(1 << info->host->this_id);
920     	switch (target) {
921     	case   1:  target = 0; break;
922     	case   2:  target = 1; break;
923     	case   4:  target = 2; break;
924     	case   8:  target = 3; break;
925     	case  16:  target = 4; break;
926     	case  32:  target = 5; break;
927     	case  64:  target = 6; break;
928     	case 128:  target = 7; break;
929     	default:   target = info->host->this_id; break;
930     	}
931     
932     	identify_msg &= 7;
933     	info->scsi.reconnected.target = target;
934     	info->scsi.reconnected.lun    = identify_msg;
935     	info->scsi.reconnected.tag    = 0;
936     
937     	ok = 0;
938     	if (info->scsi.disconnectable && info->SCpnt &&
939     	    info->SCpnt->target == target && info->SCpnt->lun == identify_msg)
940     		ok = 1;
941     
942     	if (!ok && queue_probetgtlun(&info->queues.disconnected, target, identify_msg))
943     		ok = 1;
944     
945     	msgqueue_flush(&info->scsi.msgs);
946     	if (ok) {
947     		info->scsi.phase = PHASE_RECONNECTED;
948     		outb(target, REG_SDID(info));
949     	} else {
950     		/*
951     		 * Our command structure not found - abort the
952     		 * command on the target.  Since we have no
953     		 * record of this command, we can't send
954     		 * an INITIATOR DETECTED ERROR message.
955     		 */
956     		outb(CMD_SETATN, REG_CMD(info));
957     		msgqueue_addmsg(&info->scsi.msgs, 1, ABORT);
958     		info->scsi.phase = PHASE_MSGOUT_EXPECT;
959     	}
960     
961     	outb(CMD_MSGACCEPTED, REG_CMD(info));
962     }
963     
964     /* Function: void fas216_finish_reconnect(FAS216_Info *info)
965      * Purpose : finish reconnection sequence for device
966      * Params  : info - interface which caused function done interrupt
967      */
968     static void
969     fas216_finish_reconnect(FAS216_Info *info)
970     {
971     	fas216_checkmagic(info);
972     
973     #ifdef DEBUG_CONNECT
974     	printk("Connected: %1X %1X %02X, reconnected: %1X %1X %02X\n",
975     		info->SCpnt->target, info->SCpnt->lun, info->SCpnt->tag,
976     		info->scsi.reconnected.target, info->scsi.reconnected.lun,
977     		info->scsi.reconnected.tag);
978     #endif
979     
980     	if (info->scsi.disconnectable && info->SCpnt) {
981     		info->scsi.disconnectable = 0;
982     		if (info->SCpnt->target == info->scsi.reconnected.target &&
983     		    info->SCpnt->lun    == info->scsi.reconnected.lun &&
984     		    info->SCpnt->tag    == info->scsi.reconnected.tag) {
985     #ifdef DEBUG_CONNECT
986     			printk("scsi%d.%c: reconnected",
987     				info->host->host_no, fas216_target(info));
988     #endif
989     		} else {
990     			queue_add_cmd_tail(&info->queues.disconnected, info->SCpnt);
991     #ifdef DEBUG_CONNECT
992     			printk("scsi%d.%c: had to move command to disconnected queue\n",
993     				info->host->host_no, fas216_target(info));
994     #endif
995     			info->SCpnt = NULL;
996     		}
997     	}
998     	if (!info->SCpnt) {
999     		info->SCpnt = queue_remove_tgtluntag(&info->queues.disconnected,
1000     					info->scsi.reconnected.target,
1001     					info->scsi.reconnected.lun,
1002     					info->scsi.reconnected.tag);
1003     #ifdef DEBUG_CONNECT
1004     		printk("scsi%d.%c: had to get command",
1005     			info->host->host_no, fas216_target(info));
1006     #endif
1007     	}
1008     	if (!info->SCpnt) {
1009     		outb(CMD_SETATN, REG_CMD(info));
1010     		msgqueue_flush(&info->scsi.msgs);
1011     #if 0
1012     		if (info->scsi.reconnected.tag)
1013     			msgqueue_addmsg(&info->scsi.msgs, 2, ABORT_TAG, info->scsi.reconnected.tag);
1014     		else
1015     #endif
1016     			msgqueue_addmsg(&info->scsi.msgs, 1, ABORT);
1017     		info->scsi.phase = PHASE_MSGOUT_EXPECT;
1018     		info->scsi.aborting = 1;
1019     	} else {
1020     		/*
1021     		 * Restore data pointer from SAVED data pointer
1022     		 */
1023     		info->scsi.SCp = info->SCpnt->SCp;
1024     #ifdef DEBUG_CONNECT
1025     		printk(", data pointers: [%p, %X]",
1026     			info->scsi.SCp.ptr, info->scsi.SCp.this_residual);
1027     #endif
1028     	}
1029     #ifdef DEBUG_CONNECT
1030     	printk("\n");
1031     #endif
1032     }
1033     
1034     static int fas216_wait_cmd(FAS216_Info *info, int cmd)
1035     {
1036     	int tout;
1037     	int stat;
1038     
1039     	outb(cmd, REG_CMD(info));
1040     
1041     	for (tout = 1000; tout; tout -= 1) {
1042     		stat = inb(REG_STAT(info));
1043     		if (stat & STAT_INT)
1044     			break;
1045     		udelay(1);
1046     	}
1047     
1048     	return stat;
1049     }
1050     
1051     static int fas216_get_msg_byte(FAS216_Info *info)
1052     {
1053     	int stat;
1054     
1055     	stat = fas216_wait_cmd(info, CMD_MSGACCEPTED);
1056     
1057     	if ((stat & STAT_INT) == 0)
1058     		goto timedout;
1059     
1060     	if ((stat & STAT_BUSMASK) != STAT_MESGIN)
1061     		goto unexpected_phase_change;
1062     
1063     	inb(REG_INST(info));
1064     
1065     	stat = fas216_wait_cmd(info, CMD_TRANSFERINFO);
1066     
1067     	if ((stat & STAT_INT) == 0)
1068     		goto timedout;
1069     
1070     	if ((stat & STAT_BUSMASK) != STAT_MESGIN)
1071     		goto unexpected_phase_change;
1072     
1073     	inb(REG_INST(info));
1074     
1075     	return inb(REG_FF(info));
1076     
1077     timedout:
1078     	printk("scsi%d.%c: timed out waiting for message byte\n",
1079     		info->host->host_no, fas216_target(info));
1080     	return -1;
1081     
1082     unexpected_phase_change:
1083     	printk("scsi%d.%c: unexpected phase change: status = %02X\n",
1084     		info->host->host_no, fas216_target(info), stat);
1085     
1086     	return -2;
1087     }
1088     
1089     /* Function: void fas216_message(FAS216_Info *info)
1090      * Purpose : handle a function done interrupt from FAS216 chip
1091      * Params  : info - interface which caused function done interrupt
1092      */
1093     static void fas216_message(FAS216_Info *info)
1094     {
1095     	unsigned char *message = info->scsi.message;
1096     	unsigned int msglen = 1, i;
1097     	int msgbyte = 0;
1098     
1099     	fas216_checkmagic(info);
1100     
1101     	message[0] = inb(REG_FF(info));
1102     
1103     	if (message[0] == EXTENDED_MESSAGE) {
1104     		msgbyte = fas216_get_msg_byte(info);
1105     
1106     		if (msgbyte >= 0) {
1107     			message[1] = msgbyte;
1108     
1109     			for (msglen = 2; msglen < message[1] + 2; msglen++) {
1110     				msgbyte = fas216_get_msg_byte(info);
1111     
1112     				if (msgbyte >= 0)
1113     					message[msglen] = msgbyte;
1114     				else
1115     					break;
1116     			}
1117     		}
1118     	}
1119     
1120     	info->scsi.msglen = msglen;
1121     
1122     #ifdef DEBUG_MESSAGES
1123     	{
1124     		int i;
1125     
1126     		printk("scsi%d.%c: message in: ",
1127     			info->host->host_no, fas216_target(info));
1128     		for (i = 0; i < msglen; i++)
1129     			printk("%02X ", message[i]);
1130     		printk("\n");
1131     	}
1132     #endif
1133     
1134     	if (info->scsi.phase == PHASE_RECONNECTED) {
1135     		if (message[0] == SIMPLE_QUEUE_TAG)
1136     			info->scsi.reconnected.tag = message[1];
1137     		fas216_finish_reconnect(info);
1138     		info->scsi.phase = PHASE_MSGIN;
1139     	}
1140     
1141     	switch (message[0]) {
1142     	case COMMAND_COMPLETE:
1143     		if (msglen != 1)
1144     			goto unrecognised;
1145     
1146     		printk(KERN_ERR "scsi%d.%c: command complete with no "
1147     			"status in MESSAGE_IN?\n",
1148     			info->host->host_no, fas216_target(info));
1149     		break;
1150     
1151     	case SAVE_POINTERS:
1152     		if (msglen != 1)
1153     			goto unrecognised;
1154     
1155     		/*
1156     		 * Save current data pointer to SAVED data pointer
1157     		 * SCSI II standard says that we must not acknowledge
1158     		 * this until we have really saved pointers.
1159     		 * NOTE: we DO NOT save the command nor status pointers
1160     		 * as required by the SCSI II standard.  These always
1161     		 * point to the start of their respective areas.
1162     		 */
1163     		info->SCpnt->SCp = info->scsi.SCp;
1164     		info->SCpnt->SCp.sent_command = 0;
1165     #if defined (DEBUG_MESSAGES) || defined (DEBUG_CONNECT)
1166     		printk("scsi%d.%c: save data pointers: [%p, %X]\n",
1167     			info->host->host_no, fas216_target(info),
1168     			info->scsi.SCp.ptr, info->scsi.SCp.this_residual);
1169     #endif
1170     		break;
1171     
1172     	case RESTORE_POINTERS:
1173     		if (msglen != 1)
1174     			goto unrecognised;
1175     
1176     		/*
1177     		 * Restore current data pointer from SAVED data pointer
1178     		 */
1179     		info->scsi.SCp = info->SCpnt->SCp;
1180     #if defined (DEBUG_MESSAGES) || defined (DEBUG_CONNECT)
1181     		printk("scsi%d.%c: restore data pointers: [%p, %X]\n",
1182     			info->host->host_no, fas216_target(info),
1183     			info->scsi.SCp.ptr, info->scsi.SCp.this_residual);
1184     #endif
1185     		break;
1186     
1187     	case DISCONNECT:
1188     		if (msglen != 1)
1189     			goto unrecognised;
1190     
1191     		info->scsi.phase = PHASE_MSGIN_DISCONNECT;
1192     		break;
1193     
1194     	case MESSAGE_REJECT:
1195     		if (msglen != 1)
1196     			goto unrecognised;
1197     
1198     		switch (fas216_get_last_msg(info, info->scsi.msgin_fifo)) {
1199     		case EXTENDED_MESSAGE | EXTENDED_SDTR << 8:
1200     			fas216_handlesync(info, message);
1201     			break;
1202     
1203     		case EXTENDED_MESSAGE | EXTENDED_WDTR << 8:
1204     			fas216_handlewide(info, message);
1205     			break;
1206     
1207     		default:
1208     			printk("scsi%d.%c: reject, last message %04X\n",
1209     				info->host->host_no, fas216_target(info),
1210     				fas216_get_last_msg(info, info->scsi.msgin_fifo));
1211     		}
1212     		break;
1213     
1214     	case NOP:
1215     		break;
1216     
1217     	case SIMPLE_QUEUE_TAG:
1218     		if (msglen < 2)
1219     			goto unrecognised;
1220     
1221     		/* handled above - print a warning since this is untested */
1222     		printk("scsi%d.%c: reconnect queue tag %02X\n",
1223     			info->host->host_no, fas216_target(info),
1224     			message[1]);
1225     		break;
1226     
1227     	case EXTENDED_MESSAGE:
1228     		if (msglen < 3)
1229     			goto unrecognised;
1230     
1231     		switch (message[2]) {
1232     		case EXTENDED_SDTR:	/* Sync transfer negociation request/reply */
1233     			fas216_handlesync(info, message);
1234     			break;
1235     
1236     		case EXTENDED_WDTR:	/* Wide transfer negociation request/reply */
1237     			fas216_handlewide(info, message);
1238     			break;
1239     
1240     		default:
1241     			goto unrecognised;
1242     		}
1243     		break;
1244     
1245     	default:
1246     		goto unrecognised;
1247     	}
1248     	outb(CMD_MSGACCEPTED, REG_CMD(info));
1249     	return;
1250     
1251     unrecognised:
1252     	printk("scsi%d.%c: unrecognised message, rejecting\n",
1253     		info->host->host_no, fas216_target(info));
1254     	printk("scsi%d.%c: message was", info->host->host_no, fas216_target(info));
1255     	for (i = 0; i < msglen; i++)
1256     		printk("%s%02X", i & 31 ? " " : "\n  ", message[i]);
1257     	printk("\n");
1258     
1259     	/*
1260     	 * Something strange seems to be happening here -
1261     	 * I can't use SETATN since the chip gives me an
1262     	 * invalid command interrupt when I do.  Weird.
1263     	 */
1264     outb(CMD_NOP, REG_CMD(info));
1265     fas216_dumpstate(info);
1266     	outb(CMD_SETATN, REG_CMD(info));
1267     	msgqueue_flush(&info->scsi.msgs);
1268     	msgqueue_addmsg(&info->scsi.msgs, 1, MESSAGE_REJECT);
1269     	info->scsi.phase = PHASE_MSGOUT_EXPECT;
1270     fas216_dumpstate(info);
1271     	outb(CMD_MSGACCEPTED, REG_CMD(info));
1272     }
1273     
1274     /* Function: void fas216_send_command(FAS216_Info *info)
1275      * Purpose : send a command to a target after all message bytes have been sent
1276      * Params  : info - interface which caused bus service
1277      */
1278     static void fas216_send_command(FAS216_Info *info)
1279     {
1280     	int i;
1281     
1282     	fas216_checkmagic(info);
1283     
1284     	outb(CMD_NOP|CMD_WITHDMA, REG_CMD(info));
1285     	outb(CMD_FLUSHFIFO, REG_CMD(info));
1286     
1287     	/* load command */
1288     	for (i = info->scsi.SCp.sent_command; i < info->SCpnt->cmd_len; i++)
1289     		outb(info->SCpnt->cmnd[i], REG_FF(info));
1290     
1291     	outb(CMD_TRANSFERINFO, REG_CMD(info));
1292     
1293     	info->scsi.phase = PHASE_COMMAND;
1294     }
1295     
1296     /* Function: void fas216_send_messageout(FAS216_Info *info, int start)
1297      * Purpose : handle bus service to send a message
1298      * Params  : info - interface which caused bus service
1299      * Note    : We do not allow the device to change the data direction!
1300      */
1301     static void fas216_send_messageout(FAS216_Info *info, int start)
1302     {
1303     	unsigned int tot_msglen = msgqueue_msglength(&info->scsi.msgs);
1304     
1305     	fas216_checkmagic(info);
1306     
1307     	outb(CMD_FLUSHFIFO, REG_CMD(info));
1308     
1309     	if (tot_msglen) {
1310     		struct message *msg;
1311     		int msgnr = 0;
1312     
1313     		while ((msg = msgqueue_getmsg(&info->scsi.msgs, msgnr++)) != NULL) {
1314     			int i;
1315     
1316     			for (i = start; i < msg->length; i++)
1317     				outb(msg->msg[i], REG_FF(info));
1318     
1319     			msg->fifo = tot_msglen - (inb(REG_CFIS(info)) & CFIS_CF);
1320     			start = 0;
1321     		}
1322     	} else
1323     		outb(NOP, REG_FF(info));
1324     
1325     	outb(CMD_TRANSFERINFO, REG_CMD(info));
1326     
1327     	info->scsi.phase = PHASE_MSGOUT;
1328     }
1329     
1330     /* Function: void fas216_busservice_intr(FAS216_Info *info, unsigned int stat, unsigned int ssr)
1331      * Purpose : handle a bus service interrupt from FAS216 chip
1332      * Params  : info - interface which caused bus service interrupt
1333      *           stat - Status register contents
1334      *           ssr  - SCSI Status register contents
1335      */
1336     static void fas216_busservice_intr(FAS216_Info *info, unsigned int stat, unsigned int ssr)
1337     {
1338     	fas216_checkmagic(info);
1339     
1340     #ifdef DEBUG_BUSSERVICE
1341     	printk("scsi%d.%c: bus service: stat=%02X ssr=%02X phase=%02X\n",
1342     		info->host->host_no, fas216_target(info), stat, ssr, info->scsi.phase);
1343     #endif
1344     
1345     	switch (info->scsi.phase) {
1346     	case PHASE_SELECTION:
1347     		if ((ssr & IS_BITS) != 1)
1348     			goto bad_is;
1349     		break;
1350     
1351     	case PHASE_SELSTEPS:
1352     		switch (ssr & IS_BITS) {
1353     		case IS_SELARB:
1354     		case IS_MSGBYTESENT:
1355     			goto bad_is;
1356     
1357     		case IS_NOTCOMMAND:
1358     		case IS_EARLYPHASE:
1359     			if ((stat & STAT_BUSMASK) == STAT_MESGIN)
1360     				break;
1361     			goto bad_is;
1362     
1363     		case IS_COMPLETE:
1364     			break;
1365     		}
1366     
1367     	default:
1368     		break;
1369     	}
1370     
1371     	outb(CMD_NOP, REG_CMD(info));
1372     
1373     #define STATE(st,ph) ((ph) << 3 | (st))
1374     	/* This table describes the legal SCSI state transitions,
1375     	 * as described by the SCSI II spec.
1376     	 */
1377     	switch (STATE(stat & STAT_BUSMASK, info->scsi.phase)) {
1378     						/* Reselmsgin   -> Data In	*/
1379     	case STATE(STAT_DATAIN, PHASE_RECONNECTED):
1380     		fas216_finish_reconnect(info);
1381     	case STATE(STAT_DATAIN, PHASE_SELSTEPS):/* Sel w/ steps -> Data In      */
1382     	case STATE(STAT_DATAIN, PHASE_DATAIN):  /* Data In      -> Data In      */
1383     	case STATE(STAT_DATAIN, PHASE_MSGOUT):  /* Message Out  -> Data In      */
1384     	case STATE(STAT_DATAIN, PHASE_COMMAND): /* Command      -> Data In      */
1385     	case STATE(STAT_DATAIN, PHASE_MSGIN):   /* Message In   -> Data In      */
1386     		fas216_starttransfer(info, DMA_IN, 0);
1387     		return;
1388     
1389     	case STATE(STAT_DATAOUT, PHASE_DATAOUT):/* Data Out     -> Data Out     */
1390     		fas216_starttransfer(info, DMA_OUT, 0);
1391     		return;
1392     
1393     						/* Reselmsgin   -> Data Out     */
1394     	case STATE(STAT_DATAOUT, PHASE_RECONNECTED):
1395     		fas216_finish_reconnect(info);
1396     	case STATE(STAT_DATAOUT, PHASE_SELSTEPS):/* Sel w/ steps-> Data Out     */
1397     	case STATE(STAT_DATAOUT, PHASE_MSGOUT): /* Message Out  -> Data Out     */
1398     	case STATE(STAT_DATAOUT, PHASE_COMMAND):/* Command      -> Data Out     */
1399     	case STATE(STAT_DATAOUT, PHASE_MSGIN):  /* Message In   -> Data Out     */
1400     		fas216_starttransfer(info, DMA_OUT, 1);
1401     		return;
1402     
1403     						/* Reselmsgin   -> Status       */
1404     	case STATE(STAT_STATUS, PHASE_RECONNECTED):
1405     		fas216_finish_reconnect(info);
1406     		goto status;
1407     	case STATE(STAT_STATUS, PHASE_DATAOUT): /* Data Out     -> Status       */
1408     	case STATE(STAT_STATUS, PHASE_DATAIN):  /* Data In      -> Status       */
1409     		fas216_stoptransfer(info);
1410     	case STATE(STAT_STATUS, PHASE_SELSTEPS):/* Sel w/ steps -> Status       */
1411     	case STATE(STAT_STATUS, PHASE_MSGOUT):  /* Message Out  -> Status       */
1412     	case STATE(STAT_STATUS, PHASE_COMMAND): /* Command      -> Status       */
1413     	case STATE(STAT_STATUS, PHASE_MSGIN):   /* Message In   -> Status       */
1414     	status:
1415     		outb(CMD_INITCMDCOMPLETE, REG_CMD(info));
1416     		info->scsi.phase = PHASE_STATUS;
1417     		return;
1418     
1419     	case STATE(STAT_MESGIN, PHASE_DATAOUT): /* Data Out     -> Message In   */
1420     	case STATE(STAT_MESGIN, PHASE_DATAIN):  /* Data In      -> Message In   */
1421     		fas216_stoptransfer(info);
1422     	case STATE(STAT_MESGIN, PHASE_COMMAND):	/* Command	-> Message In	*/
1423     	case STATE(STAT_MESGIN, PHASE_SELSTEPS):/* Sel w/ steps -> Message In   */
1424     	case STATE(STAT_MESGIN, PHASE_MSGOUT):  /* Message Out  -> Message In   */
1425     		info->scsi.msgin_fifo = inb(REG_CFIS(info)) & CFIS_CF;
1426     		outb(CMD_FLUSHFIFO, REG_CMD(info));
1427     		outb(CMD_TRANSFERINFO, REG_CMD(info));
1428     		info->scsi.phase = PHASE_MSGIN;
1429     		return;
1430     
1431     						/* Reselmsgin   -> Message In   */
1432     	case STATE(STAT_MESGIN, PHASE_RECONNECTED):
1433     	case STATE(STAT_MESGIN, PHASE_MSGIN):
1434     		info->scsi.msgin_fifo = inb(REG_CFIS(info)) & CFIS_CF;
1435     		outb(CMD_TRANSFERINFO, REG_CMD(info));
1436     		return;
1437     
1438     						/* Reselmsgin   -> Command      */
1439     	case STATE(STAT_COMMAND, PHASE_RECONNECTED):
1440     		fas216_finish_reconnect(info);
1441     	case STATE(STAT_COMMAND, PHASE_MSGOUT): /* Message Out  -> Command      */
1442     	case STATE(STAT_COMMAND, PHASE_MSGIN):  /* Message In   -> Command      */
1443     		fas216_send_command(info);
1444     		info->scsi.phase = PHASE_COMMAND;
1445     		return;
1446     						/* Selection    -> Message Out  */
1447     	case STATE(STAT_MESGOUT, PHASE_SELECTION):
1448     		fas216_send_messageout(info, 1);
1449     		return;
1450     						/* Any          -> Message Out  */
1451     	case STATE(STAT_MESGOUT, PHASE_MSGOUT_EXPECT):
1452     		fas216_send_messageout(info, 0);
1453     		return;
1454     
1455     	/* Error recovery rules.
1456     	 *   These either attempt to abort or retry the operation.
1457     	 * TODO: we need more of these
1458     	 */
1459     	case STATE(STAT_COMMAND, PHASE_COMMAND):/* Command      -> Command      */
1460     		/* error - we've sent out all the command bytes
1461     		 * we have.
1462     		 * NOTE: we need SAVE DATA POINTERS/RESTORE DATA POINTERS
1463     		 * to include the command bytes sent for this to work
1464     		 * correctly.
1465     		 */
1466     		printk(KERN_ERR "scsi%d.%c: "
1467     			"target trying to receive more command bytes\n",
1468     			info->host->host_no, fas216_target(info));
1469     		outb(CMD_SETATN, REG_CMD(info));
1470     		outb(15, REG_STCL(info));
1471     		outb(0, REG_STCM(info));
1472     		outb(0, REG_STCH(info));
1473     		outb(CMD_PADBYTES | CMD_WITHDMA, REG_CMD(info));
1474     		msgqueue_flush(&info->scsi.msgs);
1475     		msgqueue_addmsg(&info->scsi.msgs, 1, INITIATOR_ERROR);
1476     		info->scsi.phase = PHASE_MSGOUT_EXPECT;
1477     		return;
1478     
1479     						/* Selection    -> Message Out  */
1480     	case STATE(STAT_MESGOUT, PHASE_SELSTEPS):
1481     	case STATE(STAT_MESGOUT, PHASE_MSGOUT): /* Message Out  -> Message Out  */
1482     		/* If we get another message out phase, this
1483     		 * usually means some parity error occurred.
1484     		 * Resend complete set of messages.  If we have
1485     		 * more than 1 byte to send, we need to assert
1486     		 * ATN again.
1487     		 */
1488     		if (msgqueue_msglength(&info->scsi.msgs) > 1)
1489     			outb(CMD_SETATN, REG_CMD(info));
1490     
1491     		fas216_send_messageout(info, 0);
1492     		return;
1493     	}
1494     
1495     	if (info->scsi.phase == PHASE_MSGIN_DISCONNECT) {
1496     		printk(KERN_ERR "scsi%d.%c: disconnect message received, but bus service %s?\n",
1497     			info->host->host_no, fas216_target(info),
1498     			fas216_bus_phase(stat));
1499     		msgqueue_flush(&info->scsi.msgs);
1500     		outb(CMD_SETATN, REG_CMD(info));
1501     		msgqueue_addmsg(&info->scsi.msgs, 1, INITIATOR_ERROR);
1502     		info->scsi.phase = PHASE_MSGOUT_EXPECT;
1503     		info->scsi.aborting = 1;
1504     		outb(CMD_TRANSFERINFO, REG_CMD(info));
1505     		return;
1506     	}
1507     	printk(KERN_ERR "scsi%d.%c: bus phase %s after %s?\n",
1508     		info->host->host_no, fas216_target(info),
1509     		fas216_bus_phase(stat),
1510     		fas216_drv_phase(info));
1511     	print_debug_list();
1512     	return;
1513     
1514     bad_is:
1515     	printk("scsi%d.%c: bus service at step %d?\n",
1516     		info->host->host_no, fas216_target(info),
1517     		ssr & IS_BITS);
1518     	print_debug_list();
1519     
1520     	fas216_done(info, DID_ERROR);
1521     }
1522     
1523     /* Function: void fas216_funcdone_intr(FAS216_Info *info, unsigned int stat, unsigned int ssr)
1524      * Purpose : handle a function done interrupt from FAS216 chip
1525      * Params  : info - interface which caused function done interrupt
1526      *           stat - Status register contents
1527      *           ssr  - SCSI Status register contents
1528      */
1529     static void fas216_funcdone_intr(FAS216_Info *info, unsigned int stat, unsigned int ssr)
1530     {
1531     	int status, message;
1532     
1533     	fas216_checkmagic(info);
1534     
1535     #ifdef DEBUG_FUNCTIONDONE
1536     	printk("scsi%d.%c: function done: stat=%X ssr=%X phase=%02X\n",
1537     		info->host->host_no, fas216_target(info), stat, ssr, info->scsi.phase);
1538     #endif
1539     	switch (info->scsi.phase) {
1540     	case PHASE_STATUS:			/* status phase - read status and msg	*/
1541     		status = inb(REG_FF(info));
1542     		message = inb(REG_FF(info));
1543     		info->scsi.SCp.Message = message;
1544     		info->scsi.SCp.Status = status;
1545     		info->scsi.phase = PHASE_DONE;
1546     		outb(CMD_MSGACCEPTED, REG_CMD(info));
1547     		break;
1548     
1549     	case PHASE_IDLE:			/* reselected?				*/
1550     	case PHASE_MSGIN:			/* message in phase			*/
1551     	case PHASE_RECONNECTED:			/* reconnected command			*/
1552     		if ((stat & STAT_BUSMASK) == STAT_MESGIN) {
1553     			info->scsi.msgin_fifo = inb(REG_CFIS(info)) & CFIS_CF;
1554     			fas216_message(info);
1555     			break;
1556     		}
1557     
1558     	default:
1559     		printk("scsi%d.%c: internal phase %s for function done?"
1560     			"  What do I do with this?\n",
1561     			info->host->host_no, fas216_target(info),
1562     			fas216_drv_phase(info));
1563     	}
1564     }
1565     
1566     /* Function: void fas216_intr(struct Scsi_Host *instance)
1567      * Purpose : handle interrupts from the interface to progress a command
1568      * Params  : instance - interface to service
1569      */
1570     void fas216_intr(struct Scsi_Host *instance)
1571     {
1572     	FAS216_Info *info = (FAS216_Info *)instance->hostdata;
1573     	unsigned char isr, ssr, stat;
1574     
1575     	fas216_checkmagic(info);
1576     
1577     	stat = inb(REG_STAT(info));
1578     	ssr = inb(REG_IS(info));
1579     	isr = inb(REG_INST(info));
1580     
1581     	add_debug_list(stat, ssr, isr, info->scsi.phase);
1582     
1583     	if (stat & STAT_INT) {
1584     		if (isr & INST_BUSRESET) {
1585     			printk(KERN_DEBUG "scsi%d.H: bus reset detected\n", instance->host_no);
1586     			scsi_report_bus_reset(instance, 0);
1587     		} else if (isr & INST_ILLEGALCMD) {
1588     			printk(KERN_CRIT "scsi%d.H: illegal command given\n", instance->host_no);
1589     			fas216_dumpstate(info);
1590     		} else if (isr & INST_DISCONNECT)
1591     			fas216_disconnect_intr(info);
1592     		else if (isr & INST_RESELECTED)		/* reselected			*/
1593     			fas216_reselected_intr(info);
1594     		else if (isr & INST_BUSSERVICE)		/* bus service request		*/
1595     			fas216_busservice_intr(info, stat, ssr);
1596     		else if (isr & INST_FUNCDONE)		/* function done		*/
1597     			fas216_funcdone_intr(info, stat, ssr);
1598     		else
1599     		    	printk("scsi%d.%c: unknown interrupt received:"
1600     				" phase %s isr %02X ssr %02X stat %02X\n",
1601     				instance->host_no, fas216_target(info),
1602     				fas216_drv_phase(info), isr, ssr, stat);
1603     	}
1604     }
1605     
1606     /* Function: void fas216_kick(FAS216_Info *info)
1607      * Purpose : kick a command to the interface - interface should be idle
1608      * Params  : info - our host interface to kick
1609      * Notes   : Interrupts are always disabled!
1610      */
1611     static void fas216_kick(FAS216_Info *info)
1612     {
1613     	Scsi_Cmnd *SCpnt = NULL;
1614     	int tot_msglen, from_queue = 0, disconnect_ok;
1615     
1616     	fas216_checkmagic(info);
1617     
1618     	/*
1619     	 * Obtain the next command to process.
1620     	 */
1621     	do {
1622     		if (info->reqSCpnt) {
1623     			SCpnt = info->reqSCpnt;
1624     			info->reqSCpnt = NULL;
1625     			break;
1626     		}
1627     
1628     		if (info->origSCpnt) {
1629     			SCpnt = info->origSCpnt;
1630     			info->origSCpnt = NULL;
1631     			break;
1632     		}
1633     
1634     		/* retrieve next command */
1635     		if (!SCpnt) {
1636     			SCpnt = queue_remove_exclude(&info->queues.issue,
1637     						     info->busyluns);
1638     			from_queue = 1;
1639     			break;
1640     		}
1641     	} while (0);
1642     
1643     	if (!SCpnt) /* no command pending - just exit */
1644     		return;
1645     
1646     	if (info->scsi.disconnectable && info->SCpnt) {
1647     		queue_add_cmd_tail(&info->queues.disconnected, info->SCpnt);
1648     		info->scsi.disconnectable = 0;
1649     		info->SCpnt = NULL;
1650     		printk("scsi%d.%c: moved command to disconnected queue\n",
1651     			info->host->host_no, fas216_target(info));
1652     	}
1653     
1654     	/*
1655     	 * claim host busy
1656     	 */
1657     	info->scsi.phase = PHASE_SELECTION;
1658     	info->SCpnt = SCpnt;
1659     	info->scsi.SCp = SCpnt->SCp;
1660     	info->dma.transfer_type = fasdma_none;
1661     
1662     #ifdef DEBUG_CONNECT
1663     	printk("scsi%d.%c: starting cmd %02X",
1664     		info->host->host_no, '0' + SCpnt->target,
1665     		SCpnt->cmnd[0]);
1666     #endif
1667     
1668     	if (from_queue) {
1669     #ifdef SCSI2_TAG
1670     		/*
1671     		 * tagged queuing - allocate a new tag to this command
1672     		 */
1673     		if (SCpnt->device->tagged_queue && SCpnt->cmnd[0] != REQUEST_SENSE &&
1674     		    SCpnt->cmnd[0] != INQUIRY) {
1675     		    SCpnt->device->current_tag += 1;
1676     			if (SCpnt->device->current_tag == 0)
1677     			    SCpnt->device->current_tag = 1;
1678     				SCpnt->tag = SCpnt->device->current_tag;
1679     		} else
1680     #endif
1681     			set_bit(SCpnt->target * 8 + SCpnt->lun, info->busyluns);
1682     
1683     		info->stats.removes += 1;
1684     		switch (SCpnt->cmnd[0]) {
1685     		case WRITE_6:
1686     		case WRITE_10:
1687     		case WRITE_12:
1688     			info->stats.writes += 1;
1689     			break;
1690     		case READ_6:
1691     		case READ_10:
1692     		case READ_12:
1693     			info->stats.reads += 1;
1694     			break;
1695     		default:
1696     			info->stats.miscs += 1;
1697     			break;
1698     		}
1699     	}
1700     
1701     	/*
1702     	 * Don't allow request sense commands to disconnect.
1703     	 */
1704     	disconnect_ok = SCpnt->cmnd[0] != REQUEST_SENSE &&
1705     			info->device[SCpnt->target].disconnect_ok;
1706     
1707     	/*
1708     	 * build outgoing message bytes
1709     	 */
1710     	msgqueue_flush(&info->scsi.msgs);
1711     	msgqueue_addmsg(&info->scsi.msgs, 1, IDENTIFY(disconnect_ok, SCpnt->lun));
1712     
1713     	/*
1714     	 * add tag message if required
1715     	 */
1716     	if (SCpnt->tag)
1717     		msgqueue_addmsg(&info->scsi.msgs, 2, SIMPLE_QUEUE_TAG, SCpnt->tag);
1718     
1719     	do {
1720     #ifdef SCSI2_WIDE
1721     		if (info->device[SCpnt->target].wide_state == neg_wait) {
1722     			info->device[SCpnt->target].wide_state = neg_inprogress;
1723     			msgqueue_addmsg(&info->scsi.msgs, 4,
1724     					EXTENDED_MESSAGE, 2, EXTENDED_WDTR,
1725     					info->ifcfg.wide_max_size);
1726     			break;
1727     		}
1728     #endif
1729     #ifdef SCSI2_SYNC
1730     		if ((info->device[SCpnt->target].sync_state == neg_wait ||
1731     		     info->device[SCpnt->target].sync_state == neg_complete) &&
1732     		    (SCpnt->cmnd[0] == REQUEST_SENSE ||
1733     		     SCpnt->cmnd[0] == INQUIRY)) {
1734     			info->device[SCpnt->target].sync_state = neg_inprogress;
1735     			msgqueue_addmsg(&info->scsi.msgs, 5,
1736     					EXTENDED_MESSAGE, 3, EXTENDED_SDTR,
1737     					1000 / info->ifcfg.clockrate,
1738     					info->ifcfg.sync_max_depth);
1739     			break;
1740     		}
1741     #endif
1742     	} while (0);
1743     
1744     	/* following what the ESP driver says */
1745     	outb(0, REG_STCL(info));
1746     	outb(0, REG_STCM(info));
1747     	outb(0, REG_STCH(info));
1748     	outb(CMD_NOP | CMD_WITHDMA, REG_CMD(info));
1749     
1750     	/* flush FIFO */
1751     	outb(CMD_FLUSHFIFO, REG_CMD(info));
1752     
1753     	/* load bus-id and timeout */
1754     	outb(BUSID(SCpnt->target), REG_SDID(info));
1755     	outb(info->ifcfg.select_timeout, REG_STIM(info));
1756     
1757     	/* synchronous transfers */
1758     	fas216_set_sync(info, SCpnt->target);
1759     
1760     	tot_msglen = msgqueue_msglength(&info->scsi.msgs);
1761     
1762     #ifdef DEBUG_MESSAGES
1763     	{
1764     		struct message *msg;
1765     		int msgnr = 0, i;
1766     
1767     		printk("scsi%d.%c: message out: ",
1768     			info->host->host_no, '0' + SCpnt->target);
1769     		while ((msg = msgqueue_getmsg(&info->scsi.msgs, msgnr++)) != NULL) {
1770     			printk("{ ");
1771     			for (i = 0; i < msg->length; i++)
1772     				printk("%02x ", msg->msg[i]);
1773     			printk("} ");
1774     		}
1775     		printk("\n");
1776     	}
1777     #endif
1778     
1779     	if (tot_msglen == 1 || tot_msglen == 3) {
1780     		/*
1781     		 * We have an easy message length to send...
1782     		 */
1783     		struct message *msg;
1784     		int msgnr = 0, i;
1785     
1786     		info->scsi.phase = PHASE_SELSTEPS;
1787     
1788     		/* load message bytes */
1789     		while ((msg = msgqueue_getmsg(&info->scsi.msgs, msgnr++)) != NULL) {
1790     			for (i = 0; i < msg->length; i++)
1791     				outb(msg->msg[i], REG_FF(info));
1792     			msg->fifo = tot_msglen - (inb(REG_CFIS(info)) & CFIS_CF);
1793     		}
1794     
1795     		/* load command */
1796     		for (i = 0; i < SCpnt->cmd_len; i++)
1797     			outb(SCpnt->cmnd[i], REG_FF(info));
1798     
1799     		if (tot_msglen == 1)
1800     			outb(CMD_SELECTATN, REG_CMD(info));
1801     		else
1802     			outb(CMD_SELECTATN3, REG_CMD(info));
1803     	} else {
1804     		/*
1805     		 * We have an unusual number of message bytes to send.
1806     		 *  Load first byte into fifo, and issue SELECT with ATN and
1807     		 *  stop steps.
1808     		 */
1809     		struct message *msg = msgqueue_getmsg(&info->scsi.msgs, 0);
1810     
1811     		outb(msg->msg[0], REG_FF(info));
1812     		msg->fifo = 1;
1813     
1814     		outb(CMD_SELECTATNSTOP, REG_CMD(info));
1815     	}
1816     
1817     #ifdef DEBUG_CONNECT
1818     	printk(", data pointers [%p, %X]\n",
1819     		info->scsi.SCp.ptr, info->scsi.SCp.this_residual);
1820     #endif
1821     	/* should now get either DISCONNECT or (FUNCTION DONE with BUS SERVICE) intr */
1822     }
1823     
1824     /* Function: void fas216_rq_sns_done(info, SCpnt, result)
1825      * Purpose : Finish processing automatic request sense command
1826      * Params  : info   - interface that completed
1827      *	     SCpnt  - command that completed
1828      *	     result - driver byte of result
1829      */
1830     static void
1831     fas216_rq_sns_done(FAS216_Info *info, Scsi_Cmnd *SCpnt, unsigned int result)
1832     {
1833     #ifdef DEBUG_CONNECT
1834     	printk("scsi%d.%c: request sense complete, result=%04X%02X%02X\n",
1835     		info->host->host_no, '0' + SCpnt->target, result,
1836     		SCpnt->SCp.Message, SCpnt->SCp.Status);
1837     #endif
1838     
1839     	if (result != DID_OK || SCpnt->SCp.Status != GOOD)
1840     		/*
1841     		 * Something went wrong.  Make sure that we don't
1842     		 * have valid data in the sense buffer that could
1843     		 * confuse the higher levels.
1844     		 */
1845     		memset(SCpnt->sense_buffer, 0, sizeof(SCpnt->sense_buffer));
1846     
1847     	/*
1848     	 * Note that we don't set SCpnt->result, since that should
1849     	 * reflect the status of the command that we were asked by
1850     	 * the upper layers to process.  This would have been set
1851     	 * correctly by fas216_std_done.
1852     	 */
1853     	SCpnt->scsi_done(SCpnt);
1854     }
1855     
1856     /* Function: void fas216_std_done(info, SCpnt, result)
1857      * Purpose : Finish processing of standard command
1858      * Params  : info   - interface that completed
1859      *	     SCpnt  - command that completed
1860      *	     result - driver byte of result
1861      */
1862     static void
1863     fas216_std_done(FAS216_Info *info, Scsi_Cmnd *SCpnt, unsigned int result)
1864     {
1865     	info->stats.fins += 1;
1866     
1867     	SCpnt->result = result << 16 | info->scsi.SCp.Message << 8 |
1868     			info->scsi.SCp.Status;
1869     
1870     #ifdef DEBUG_CONNECT
1871     	printk("scsi%d.%c: command complete, result=%08X, command=",
1872     		info->host->host_no, '0' + SCpnt->target, SCpnt->result);
1873     	print_command(SCpnt->cmnd);
1874     #endif
1875     
1876     	/*
1877     	 * If the driver detected an error, or the command
1878     	 * was request sense, then we're all done.
1879     	 */
1880     	if (result != DID_OK || SCpnt->cmnd[0] == REQUEST_SENSE)
1881     		goto done;
1882     
1883     	/*
1884     	 * If the command returned CHECK_CONDITION status,
1885     	 * request the sense information.
1886     	 */
1887     	if (info->scsi.SCp.Status == CHECK_CONDITION)
1888     		goto request_sense;
1889     
1890     	/*
1891     	 * If the command did not complete with GOOD status,
1892     	 * we are all done here.
1893     	 */
1894     	if (info->scsi.SCp.Status != GOOD)
1895     		goto done;
1896     
1897     	/*
1898     	 * We have successfully completed a command.  Make sure that
1899     	 * we do not have any buffers left to transfer.  The world
1900     	 * is not perfect, and we seem to occasionally hit this.
1901     	 * It can be indicative of a buggy driver, target or the upper
1902     	 * levels of the SCSI code.
1903     	 */
1904     	if (info->scsi.SCp.ptr) {
1905     		switch (SCpnt->cmnd[0]) {
1906     		case INQUIRY:
1907     		case START_STOP:
1908     //		case READ_CAPACITY:
1909     		case MODE_SENSE:
1910     			break;
1911     
1912     		default:
1913     			printk(KERN_ERR "scsi%d.%c: incomplete data transfer "
1914     				"detected: res=%08X ptr=%p len=%X command=",
1915     				info->host->host_no, '0' + SCpnt->target,
1916     				SCpnt->result, info->scsi.SCp.ptr,
1917     				info->scsi.SCp.this_residual);
1918     			print_command(SCpnt->cmnd);
1919     		}
1920     	}
1921     
1922     done:	SCpnt->scsi_done(SCpnt);
1923     	return;
1924     
1925     request_sense:
1926     	memset(SCpnt->cmnd, 0, sizeof (SCpnt->cmnd));
1927     	SCpnt->cmnd[0] = REQUEST_SENSE;
1928     	SCpnt->cmnd[1] = SCpnt->lun << 5;
1929     	SCpnt->cmnd[4] = sizeof(SCpnt->sense_buffer);
1930     	SCpnt->cmd_len = COMMAND_SIZE(SCpnt->cmnd[0]);
1931     	SCpnt->SCp.buffer = NULL;
1932     	SCpnt->SCp.buffers_residual = 0;
1933     	SCpnt->SCp.ptr = (char *)SCpnt->sense_buffer;
1934     	SCpnt->SCp.this_residual = sizeof(SCpnt->sense_buffer);
1935     	SCpnt->SCp.Message = 0;
1936     	SCpnt->SCp.Status = 0;
1937     	SCpnt->sc_data_direction = SCSI_DATA_READ;
1938     	SCpnt->use_sg = 0;
1939     	SCpnt->tag = 0;
1940     	SCpnt->host_scribble = (void *)fas216_rq_sns_done;
1941     
1942     	/*
1943     	 * Place this command into the high priority "request
1944     	 * sense" slot.  This will be the very next command
1945     	 * executed, unless a target connects to us.
1946     	 */
1947     	if (info->reqSCpnt)
1948     		printk(KERN_WARNING "scsi%d.%c: loosing request command\n",
1949     			info->host->host_no, '0' + SCpnt->target);
1950     	info->reqSCpnt = SCpnt;
1951     }
1952     
1953     /* Function: void fas216_done(FAS216_Info *info, unsigned int result)
1954      * Purpose : complete processing for current command
1955      * Params  : info   - interface that completed
1956      *	     result - driver byte of result
1957      */
1958     static void fas216_done(FAS216_Info *info, unsigned int result)
1959     {
1960     	void (*fn)(FAS216_Info *, Scsi_Cmnd *, unsigned int);
1961     	Scsi_Cmnd *SCpnt;
1962     
1963     	fas216_checkmagic(info);
1964     
1965     	if (!info->SCpnt)
1966     		goto no_command;
1967     
1968     	SCpnt = info->SCpnt;
1969     	info->SCpnt = NULL;
1970         	info->scsi.phase = PHASE_IDLE;
1971     
1972     	if (!SCpnt->scsi_done)
1973     		goto no_done;
1974     
1975     	if (info->scsi.aborting) {
1976     		printk("scsi%d.%c: uncaught abort - returning DID_ABORT\n",
1977     			info->host->host_no, fas216_target(info));
1978     		result = DID_ABORT;
1979     		info->scsi.aborting = 0;
1980     	}
1981     
1982     	/*
1983     	 * Sanity check the completion - if we have zero bytes left
1984     	 * to transfer, we should not have a valid pointer.
1985     	 */
1986     	if (info->scsi.SCp.ptr && info->scsi.SCp.this_residual == 0) {
1987     		printk("scsi%d.%c: zero bytes left to transfer, but "
1988     		       "buffer pointer still valid: ptr=%p len=%08x command=",
1989     		       info->host->host_no, '0' + SCpnt->target,
1990     		       info->scsi.SCp.ptr, info->scsi.SCp.this_residual);
1991     		info->scsi.SCp.ptr = NULL;
1992     		print_command(SCpnt->cmnd);
1993     	}
1994     
1995     	/*
1996     	 * Clear down this command as completed.  If we need to request
1997     	 * the sense information, fas216_kick will re-assert the busy
1998     	 * status.
1999     	 */
2000     	clear_bit(SCpnt->target * 8 + SCpnt->lun, info->busyluns);
2001     
2002     	fn = (void (*)(FAS216_Info *, Scsi_Cmnd *, unsigned int))SCpnt->host_scribble;
2003     	fn(info, SCpnt, result);
2004     
2005     	if (info->scsi.irq != NO_IRQ)
2006     		fas216_kick(info);
2007     	return;
2008     
2009     no_command:
2010     	panic("scsi%d.H: null command in fas216_done",
2011     		info->host->host_no);
2012     no_done:
2013     	panic("scsi%d.H: null scsi_done function in fas216_done",
2014     		info->host->host_no);
2015     }
2016     
2017     /* Function: int fas216_queue_command(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *))
2018      * Purpose : queue a command for adapter to process.
2019      * Params  : SCpnt - Command to queue
2020      *	     done  - done function to call once command is complete
2021      * Returns : 0 - success, else error
2022      * Notes   : io_request_lock is held, interrupts are disabled.
2023      */
2024     int fas216_queue_command(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *))
2025     {
2026     	FAS216_Info *info = (FAS216_Info *)SCpnt->host->hostdata;
2027     	int result;
2028     
2029     	fas216_checkmagic(info);
2030     
2031     #ifdef DEBUG_CONNECT
2032     	printk("scsi%d.%c: received queuable command (%p) %02X\n",
2033     		SCpnt->host->host_no, '0' + SCpnt->target,
2034     		SCpnt, SCpnt->cmnd[0]);
2035     #endif
2036     
2037     	SCpnt->scsi_done = done;
2038     	SCpnt->host_scribble = (void *)fas216_std_done;
2039     	SCpnt->result = 0;
2040     	SCpnt->SCp.Message = 0;
2041     	SCpnt->SCp.Status = 0;
2042     
2043     	if (SCpnt->use_sg) {
2044     		unsigned long len = 0;
2045     		int buf;
2046     
2047     		SCpnt->SCp.buffer = (struct scatterlist *) SCpnt->buffer;
2048     		SCpnt->SCp.buffers_residual = SCpnt->use_sg - 1;
2049     		SCpnt->SCp.ptr = (char *) SCpnt->SCp.buffer->address;
2050     		SCpnt->SCp.this_residual = SCpnt->SCp.buffer->length;
2051     		/*
2052     		 * Calculate correct buffer length.  Some commands
2053     		 * come in with the wrong request_bufflen.
2054     		 */
2055     		for (buf = 0; buf <= SCpnt->SCp.buffers_residual; buf++)
2056     			len += SCpnt->SCp.buffer[buf].length;
2057     
2058     		if (SCpnt->request_bufflen != len)
2059     			printk(KERN_WARNING "scsi%d.%c: bad request buffer "
2060     			       "length %d, should be %ld\n", info->host->host_no,
2061     			       '0' + SCpnt->target, SCpnt->request_bufflen, len);
2062     		SCpnt->request_bufflen = len;
2063     	} else {
2064     		SCpnt->SCp.buffer = NULL;
2065     		SCpnt->SCp.buffers_residual = 0;
2066     		SCpnt->SCp.ptr = (unsigned char *)SCpnt->request_buffer;
2067     		SCpnt->SCp.this_residual = SCpnt->request_bufflen;
2068     	}
2069     
2070     	/*
2071     	 * If the upper SCSI layers pass a buffer, but zero length,
2072     	 * we aren't interested in the buffer pointer.
2073     	 */
2074     	if (SCpnt->SCp.this_residual == 0 && SCpnt->SCp.ptr) {
2075     #if 0
2076     		printk(KERN_WARNING "scsi%d.%c: zero length buffer passed for "
2077     		       "command ", info->host->host_no, '0' + SCpnt->target);
2078     		print_command(SCpnt->cmnd);
2079     #endif
2080     		SCpnt->SCp.ptr = NULL;
2081     	}
2082     
2083     	info->stats.queues += 1;
2084     	SCpnt->tag = 0;
2085     
2086     	/*
2087     	 * Add command into execute queue and let it complete under
2088     	 * whatever scheme we're using.
2089     	 */
2090     	result = !queue_add_cmd_ordered(&info->queues.issue, SCpnt);
2091     
2092     	/*
2093     	 * If we successfully added the command,
2094     	 * kick the interface to get it moving.
2095     	 */
2096     	if (result == 0 && (!info->SCpnt || info->scsi.disconnectable))
2097     		fas216_kick(info);
2098     
2099     	return result;
2100     }
2101     
2102     /* Function: void fas216_internal_done(Scsi_Cmnd *SCpnt)
2103      * Purpose : trigger restart of a waiting thread in fas216_command
2104      * Params  : SCpnt - Command to wake
2105      */
2106     static void fas216_internal_done(Scsi_Cmnd *SCpnt)
2107     {
2108     	FAS216_Info *info = (FAS216_Info *)SCpnt->host->hostdata;
2109     
2110     	fas216_checkmagic(info);
2111     
2112     	info->internal_done = 1;
2113     }
2114     
2115     /* Function: int fas216_command(Scsi_Cmnd *SCpnt)
2116      * Purpose : queue a command for adapter to process.
2117      * Params  : SCpnt - Command to queue
2118      * Returns : scsi result code
2119      * Notes   : io_request_lock is held, interrupts are disabled.
2120      */
2121     int fas216_command(Scsi_Cmnd *SCpnt)
2122     {
2123     	FAS216_Info *info = (FAS216_Info *)SCpnt->host->hostdata;
2124     
2125     	fas216_checkmagic(info);
2126     
2127     	/*
2128     	 * We should only be using this if we don't have an interrupt.
2129     	 * Provide some "incentive" to use the queueing code.
2130     	 */
2131     	if (info->scsi.irq != NO_IRQ)
2132     		BUG();
2133     
2134     	info->internal_done = 0;
2135     	fas216_queue_command(SCpnt, fas216_internal_done);
2136     
2137     	/*
2138     	 * This wastes time, since we can't return until the command is
2139     	 * complete. We can't sleep either since we may get re-entered!
2140     	 * However, we must re-enable interrupts, or else we'll be
2141     	 * waiting forever.
2142     	 */
2143     	spin_unlock_irq(&io_request_lock);
2144     
2145     	while (!info->internal_done) {
2146     		/*
2147     		 * If we don't have an IRQ, then we must poll the card for
2148     		 * it's interrupt, and use that to call this driver's
2149     		 * interrupt routine.  That way, we keep the command
2150     		 * progressing.  Maybe we can add some inteligence here
2151     		 * and go to sleep if we know that the device is going
2152     		 * to be some time (eg, disconnected).
2153     		 */
2154     		if (inb(REG_STAT(info)) & STAT_INT) {
2155     			spin_lock_irq(&io_request_lock);
2156     			fas216_intr(info->host);
2157     			spin_unlock_irq(&io_request_lock);
2158     		}
2159     	}
2160     
2161     	spin_lock_irq(&io_request_lock);
2162     
2163     	return SCpnt->result;
2164     }
2165     
2166     enum res_abort {
2167     	res_failed,		/* unable to abort		*/
2168     	res_success,		/* command on issue queue	*/
2169     	res_success_clear,	/* command marked tgt/lun busy	*/
2170     	res_hw_abort		/* command on disconnected dev	*/
2171     };
2172     
2173     /*
2174      * Prototype: enum res_abort fas216_do_abort(FAS216_Info *info, Scsi_Cmnd *SCpnt)
2175      * Purpose  : decide how to abort a command
2176      * Params   : SCpnt - command to abort
2177      * Returns  : abort status
2178      */
2179     static enum res_abort
2180     fas216_do_abort(FAS216_Info *info, Scsi_Cmnd *SCpnt)
2181     {
2182     	enum res_abort res = res_failed;
2183     
2184     	if (queue_remove_cmd(&info->queues.issue, SCpnt)) {
2185     		/*
2186     		 * The command was on the issue queue, and has not been
2187     		 * issued yet.  We can remove the command from the queue,
2188     		 * and acknowledge the abort.  Neither the device nor the
2189     		 * interface know about the command.
2190     		 */
2191     		printk("on issue queue ");
2192     
2193     		res = res_success;
2194     	} else if (queue_remove_cmd(&info->queues.disconnected, SCpnt)) {
2195     		/*
2196     		 * The command was on the disconnected queue.  We must
2197     		 * reconnect with the device if possible, and send it
2198     		 * an abort message.
2199     		 */
2200     		printk("on disconnected queue ");
2201     
2202     		res = res_hw_abort;
2203     	} else if (info->SCpnt == SCpnt) {
2204     		printk("executing ");
2205     
2206     		switch (info->scsi.phase) {
2207     		/*
2208     		 * If the interface is idle, and the command is 'disconnectable',
2209     		 * then it is the same as on the disconnected queue.
2210     		 */
2211     		case PHASE_IDLE:
2212     			if (info->scsi.disconnectable) {
2213     				info->scsi.disconnectable = 0;
2214     				info->SCpnt = NULL;
2215     				res = res_hw_abort;
2216     			}
2217     			break;
2218     
2219     		default:
2220     			break;
2221     		}
2222     	} else if (info->origSCpnt == SCpnt) {
2223     		/*
2224     		 * The command will be executed next, but a command
2225     		 * is currently using the interface.  This is similar to
2226     		 * being on the issue queue, except the busylun bit has
2227     		 * been set.
2228     		 */
2229     		info->origSCpnt = NULL;
2230     		printk("waiting for execution ");
2231     		res = res_success_clear;
2232     	} else
2233     		printk("unknown ");
2234     
2235     	return res;
2236     }
2237     
2238     /* Function: int fas216_eh_abort(Scsi_Cmnd *SCpnt)
2239      * Purpose : abort this command
2240      * Params  : SCpnt - command to abort
2241      * Returns : FAILED if unable to abort
2242      * Notes   : io_request_lock is taken, and irqs are disabled
2243      */
2244     int fas216_eh_abort(Scsi_Cmnd *SCpnt)
2245     {
2246     	FAS216_Info *info = (FAS216_Info *)SCpnt->host->hostdata;
2247     	int result = FAILED;
2248     
2249     	fas216_checkmagic(info);
2250     
2251     	info->stats.aborts += 1;
2252     
2253     	print_debug_list();
2254     	fas216_dumpstate(info);
2255     	fas216_dumpinfo(info);
2256     
2257     	printk(KERN_WARNING "scsi%d: abort ", info->host->host_no);
2258     
2259     	switch (fas216_do_abort(info, SCpnt)) {
2260     	/*
2261     	 * We managed to find the command and cleared it out.
2262     	 * We do not expect the command to be executing on the
2263     	 * target, but we have set the busylun bit.
2264     	 */
2265     	case res_success_clear:
2266     		printk("clear ");
2267     		clear_bit(SCpnt->target * 8 + SCpnt->lun, info->busyluns);
2268     
2269     	/*
2270     	 * We found the command, and cleared it out.  Either
2271     	 * the command is still known to be executing on the
2272     	 * target, or the busylun bit is not set.
2273     	 */
2274     	case res_success:
2275     		printk("success\n");
2276     		result = SUCCESS;
2277     		break;
2278     
2279     	/*
2280     	 * We need to reconnect to the target and send it an
2281     	 * ABORT or ABORT_TAG message.  We can only do this
2282     	 * if the bus is free.
2283     	 */
2284     	case res_hw_abort:
2285     		
2286     
2287     	/*
2288     	 * We are unable to abort the command for some reason.
2289     	 */
2290     	default:
2291     	case res_failed:
2292     		printk("failed\n");
2293     		break;
2294     	}
2295     
2296     	return result;
2297     }
2298     
2299     /* Function: void fas216_reset_state(FAS216_Info *info)
2300      * Purpose : Initialise driver internal state
2301      * Params  : info - state to initialise
2302      */
2303     static void fas216_reset_state(FAS216_Info *info)
2304     {
2305     	neg_t sync_state, wide_state;
2306     	int i;
2307     
2308     	fas216_checkmagic(info);
2309     
2310     	/*
2311     	 * Clear out all stale info in our state structure
2312     	 */
2313     	memset(info->busyluns, 0, sizeof(info->busyluns));
2314     	msgqueue_flush(&info->scsi.msgs);
2315     	info->scsi.reconnected.target = 0;
2316     	info->scsi.reconnected.lun = 0;
2317     	info->scsi.reconnected.tag = 0;
2318     	info->scsi.disconnectable = 0;
2319     	info->scsi.aborting = 0;
2320     	info->scsi.phase = PHASE_IDLE;
2321     	info->scsi.async_stp =
2322     			fas216_syncperiod(info, info->ifcfg.asyncperiod);
2323     
2324     	if (info->ifcfg.wide_max_size == 0)
2325     		wide_state = neg_invalid;
2326     	else
2327     #ifdef SCSI2_WIDE
2328     		wide_state = neg_wait;
2329     #else
2330     		wide_state = neg_invalid;
2331     #endif
2332     
2333     	if (info->host->dma_channel == NO_DMA || !info->dma.setup)
2334     		sync_state = neg_invalid;
2335     	else
2336     #ifdef SCSI2_SYNC
2337     		sync_state = neg_wait;
2338     #else
2339     		sync_state = neg_invalid;
2340     #endif
2341     
2342     	for (i = 0; i < 8; i++) {
2343     		info->device[i].disconnect_ok	= info->ifcfg.disconnect_ok;
2344     		info->device[i].sync_state	= sync_state;
2345     		info->device[i].wide_state	= wide_state;
2346     		info->device[i].period		= info->ifcfg.asyncperiod / 4;
2347     		info->device[i].stp		= info->scsi.async_stp;
2348     		info->device[i].sof		= 0;
2349     		info->device[i].wide_xfer	= 0;
2350     	}
2351     
2352     	/*
2353     	 * Drain all commands on disconnected queue
2354     	 */
2355     	while (queue_remove(&info->queues.disconnected) != NULL);
2356     
2357     	/*
2358     	 * Remove executing commands.
2359     	 */
2360     	info->SCpnt     = NULL;
2361     	info->reqSCpnt  = NULL;
2362     	info->origSCpnt = NULL;
2363     }
2364     
2365     /* Function: int fas216_eh_device_reset(Scsi_Cmnd *SCpnt)
2366      * Purpose : Reset the device associated with this command
2367      * Params  : SCpnt - command specifing device to reset
2368      * Returns : FAILED if unable to reset
2369      */
2370     int fas216_eh_device_reset(Scsi_Cmnd *SCpnt)
2371     {
2372     	FAS216_Info *info = (FAS216_Info *)SCpnt->host->hostdata;
2373     
2374     	printk("scsi%d.%c: "__FUNCTION__": called\n",
2375     		info->host->host_no, '0' + SCpnt->target);
2376     	return FAILED;
2377     }
2378     
2379     /* Function: int fas216_eh_bus_reset(Scsi_Cmnd *SCpnt)
2380      * Purpose : Reset the bus associated with the command
2381      * Params  : SCpnt - command specifing bus to reset
2382      * Returns : FAILED if unable to reset
2383      * Notes   : io_request_lock is taken, and irqs are disabled
2384      */
2385     int fas216_eh_bus_reset(Scsi_Cmnd *SCpnt)
2386     {
2387     	FAS216_Info *info = (FAS216_Info *)SCpnt->host->hostdata;
2388     	int result = FAILED;
2389     
2390     	fas216_checkmagic(info);
2391     
2392     	info->stats.bus_resets += 1;
2393     
2394     	printk("scsi%d.%c: "__FUNCTION__": resetting bus\n",
2395     		info->host->host_no, '0' + SCpnt->target);
2396     
2397     	/*
2398     	 * Attempt to stop all activity on this interface.
2399     	 */
2400     	outb(info->scsi.cfg[2], REG_CNTL3(info));
2401     	fas216_stoptransfer(info);
2402     
2403     	/*
2404     	 * Clear any pending interrupts
2405     	 */
2406     	while (inb(REG_STAT(info)) & STAT_INT)
2407     		inb(REG_INST(info));
2408     
2409     	/*
2410     	 * Reset the SCSI bus
2411     	 */
2412     	outb(CMD_RESETSCSI, REG_CMD(info));
2413     	udelay(5);
2414     
2415     	/*
2416     	 * Clear reset interrupt
2417     	 */
2418     	if (inb(REG_STAT(info)) & STAT_INT &&
2419     	    inb(REG_INST(info)) & INST_BUSRESET)
2420     		result = SUCCESS;
2421     
2422     	fas216_reset_state(info);
2423     
2424     	return result;
2425     }
2426     
2427     /* Function: void fas216_init_chip(FAS216_Info *info)
2428      * Purpose : Initialise FAS216 state after reset
2429      * Params  : info - state structure for interface
2430      */
2431     static void fas216_init_chip(FAS216_Info *info)
2432     {
2433     	outb(fas216_clockrate(info->ifcfg.clockrate), REG_CLKF(info));
2434     	outb(info->scsi.cfg[0], REG_CNTL1(info));
2435     	outb(info->scsi.cfg[1], REG_CNTL2(info));
2436     	outb(info->scsi.cfg[2], REG_CNTL3(info));
2437     	outb(info->ifcfg.select_timeout, REG_STIM(info));
2438     	outb(0, REG_SOF(info));
2439     	outb(info->scsi.async_stp, REG_STP(info));
2440     	outb(info->scsi.cfg[0], REG_CNTL1(info));
2441     }
2442     
2443     /* Function: int fas216_eh_host_reset(Scsi_Cmnd *SCpnt)
2444      * Purpose : Reset the host associated with this command
2445      * Params  : SCpnt - command specifing host to reset
2446      * Returns : FAILED if unable to reset
2447      * Notes   : io_request_lock is taken, and irqs are disabled
2448      */
2449     int fas216_eh_host_reset(Scsi_Cmnd *SCpnt)
2450     {
2451     	FAS216_Info *info = (FAS216_Info *)SCpnt->host->hostdata;
2452     
2453     	fas216_checkmagic(info);
2454     
2455     	printk("scsi%d.%c: "__FUNCTION__": resetting host\n",
2456     		info->host->host_no, '0' + SCpnt->target);
2457     
2458     	/*
2459     	 * Reset the SCSI chip.
2460     	 */
2461     	outb(CMD_RESETCHIP, REG_CMD(info));
2462     
2463     	/*
2464     	 * Ugly ugly ugly!
2465     	 * We need to release the io_request_lock and enable
2466     	 * IRQs if we sleep, but we must relock and disable
2467     	 * IRQs after the sleep.
2468     	 */
2469     	spin_unlock_irq(&io_request_lock);
2470     	scsi_sleep(25*HZ/100);
2471     	spin_lock_irq(&io_request_lock);
2472     
2473     	/*
2474     	 * Release the SCSI reset.
2475     	 */
2476     	outb(CMD_NOP, REG_CMD(info));
2477     
2478     	fas216_init_chip(info);
2479     
2480     	return SUCCESS;
2481     }
2482     
2483     #define TYPE_UNKNOWN	0
2484     #define TYPE_NCR53C90	1
2485     #define TYPE_NCR53C90A	2
2486     #define TYPE_NCR53C9x	3
2487     #define TYPE_Am53CF94	4
2488     #define TYPE_EmFAS216	5
2489     #define TYPE_QLFAS216	6
2490     
2491     static char *chip_types[] = {
2492     	"unknown",
2493     	"NS NCR53C90",
2494     	"NS NCR53C90A",
2495     	"NS NCR53C9x",
2496     	"AMD Am53CF94",
2497     	"Emulex FAS216",
2498     	"QLogic FAS216"
2499     };
2500     
2501     static int fas216_detect_type(FAS216_Info *info)
2502     {
2503     	int family, rev;
2504     
2505     	/*
2506     	 * Reset the chip.
2507     	 */
2508     	outb(CMD_RESETCHIP, REG_CMD(info));
2509     	udelay(50);
2510     	outb(CMD_NOP, REG_CMD(info));
2511     
2512     	/*
2513     	 * Check to see if control reg 2 is present.
2514     	 */
2515     	outb(0, REG_CNTL3(info));
2516     	outb(CNTL2_S2FE, REG_CNTL2(info));
2517     
2518     	/*
2519     	 * If we are unable to read back control reg 2
2520     	 * correctly, it is not present, and we have a
2521     	 * NCR53C90.
2522     	 */
2523     	if ((inb(REG_CNTL2(info)) & (~0xe0)) != CNTL2_S2FE)
2524     		return TYPE_NCR53C90;
2525     
2526     	/*
2527     	 * Now, check control register 3
2528     	 */
2529     	outb(0, REG_CNTL2(info));
2530     	outb(0, REG_CNTL3(info));
2531     	outb(5, REG_CNTL3(info));
2532     
2533     	/*
2534     	 * If we are unable to read the register back
2535     	 * correctly, we have a NCR53C90A
2536     	 */
2537     	if (inb(REG_CNTL3(info)) != 5)
2538     		return TYPE_NCR53C90A;
2539     
2540     	/*
2541     	 * Now read the ID from the chip.
2542     	 */
2543     	outb(0, REG_CNTL3(info));
2544     
2545     	outb(CNTL3_ADIDCHK, REG_CNTL3(info));
2546     	outb(0, REG_CNTL3(info));
2547     
2548     	outb(CMD_RESETCHIP, REG_CMD(info));
2549     	udelay(5);
2550     	outb(CMD_WITHDMA | CMD_NOP, REG_CMD(info));
2551     
2552     	outb(CNTL2_ENF, REG_CNTL2(info));
2553     	outb(CMD_RESETCHIP, REG_CMD(info));
2554     	udelay(5);
2555     	outb(CMD_NOP, REG_CMD(info));
2556     
2557     	rev     = inb(REG1_ID(info));
2558     	family  = rev >> 3;
2559     	rev    &= 7;
2560     
2561     	switch (family) {
2562     	case 0x01:
2563     		if (rev == 4)
2564     			return TYPE_Am53CF94;
2565     		break;
2566     
2567     	case 0x02:
2568     		switch (rev) {
2569     		case 2:
2570     			return TYPE_EmFAS216;
2571     		case 3:
2572     			return TYPE_QLFAS216;
2573     		}
2574     		break;
2575     
2576     	default:
2577     		break;
2578     	}
2579     	printk("family %x rev %x\n", family, rev);
2580     	return TYPE_NCR53C9x;
2581     }
2582     
2583     /* Function: int fas216_init(struct Scsi_Host *instance)
2584      * Purpose : initialise FAS/NCR/AMD SCSI ic.
2585      * Params  : instance - a driver-specific filled-out structure
2586      * Returns : 0 on success
2587      */
2588     int fas216_init(struct Scsi_Host *instance)
2589     {
2590     	FAS216_Info *info = (FAS216_Info *)instance->hostdata;
2591     	int type;
2592     
2593     	info->magic_start = MAGIC;
2594     	info->magic_end   = MAGIC;
2595     	info->host        = instance;
2596     	info->scsi.cfg[0] = instance->this_id;
2597     	info->scsi.cfg[1] = CNTL2_ENF | CNTL2_S2FE;
2598     	info->scsi.cfg[2] = info->ifcfg.cntl3 | CNTL3_ADIDCHK | CNTL3_G2CB;
2599     
2600     	memset(&info->stats, 0, sizeof(info->stats));
2601     
2602     	msgqueue_initialise(&info->scsi.msgs);
2603     
2604     	if (!queue_initialise(&info->queues.issue))
2605     		return 1;
2606     
2607     	if (!queue_initialise(&info->queues.disconnected)) {
2608     		queue_free(&info->queues.issue);
2609     		return 1;
2610     	}
2611     
2612     	fas216_reset_state(info);
2613     	type = fas216_detect_type(info);
2614     	info->scsi.type = chip_types[type];
2615     
2616     	udelay(300);
2617     
2618     	/*
2619     	 * Initialise the chip correctly.
2620     	 */
2621     	fas216_init_chip(info);
2622     
2623     	/*
2624     	 * Reset the SCSI bus.  We don't want to see
2625     	 * the resulting reset interrupt, so mask it
2626     	 * out.
2627     	 */
2628     	outb(info->scsi.cfg[0] | CNTL1_DISR, REG_CNTL1(info));
2629     	outb(CMD_RESETSCSI, REG_CMD(info));
2630     
2631     	/*
2632     	 * scsi standard says wait 250ms
2633     	 */
2634     	spin_unlock_irq(&io_request_lock);
2635     	scsi_sleep(25*HZ/100);
2636     	spin_lock_irq(&io_request_lock);
2637     
2638     	outb(info->scsi.cfg[0], REG_CNTL1(info));
2639     	inb(REG_INST(info));
2640     
2641     	fas216_checkmagic(info);
2642     
2643     	return 0;
2644     }
2645     
2646     /* Function: int fas216_release(struct Scsi_Host *instance)
2647      * Purpose : release all resources and put everything to bed for
2648      *           FAS/NCR/AMD SCSI ic.
2649      * Params  : instance - a driver-specific filled-out structure
2650      * Returns : 0 on success
2651      */
2652     int fas216_release(struct Scsi_Host *instance)
2653     {
2654     	FAS216_Info *info = (FAS216_Info *)instance->hostdata;
2655     
2656     	fas216_checkmagic(info);
2657     
2658     	outb(CMD_RESETCHIP, REG_CMD(info));
2659     	queue_free(&info->queues.disconnected);
2660     	queue_free(&info->queues.issue);
2661     
2662     	return 0;
2663     }
2664     
2665     /*
2666      * Function: int fas216_info(FAS216_Info *info, char *buffer)
2667      * Purpose : generate a string containing information about this
2668      *	     host.
2669      * Params  : info   - FAS216 host information
2670      *	     buffer - string buffer to build string
2671      * Returns : size of built string
2672      */
2673     int fas216_info(FAS216_Info *info, char *buffer)
2674     {
2675     	char *p = buffer;
2676     
2677     	p += sprintf(p, "(%s) at port 0x%08lX ",
2678     		     info->scsi.type, info->host->io_port);
2679     
2680     	if (info->host->irq != NO_IRQ)
2681     		p += sprintf(p, "irq %d ", info->host->irq);
2682     	else
2683     		p += sprintf(p, "no irq ");
2684     
2685     	if (info->host->dma_channel != NO_DMA)
2686     		p += sprintf(p, "dma %d ", info->host->dma_channel);
2687     	else
2688     		p += sprintf(p, "no dma ");
2689     
2690     	return p - buffer;
2691     }
2692     
2693     int fas216_print_host(FAS216_Info *info, char *buffer)
2694     {
2695     	
2696     	return sprintf(buffer,
2697     			"\n"
2698     			"Chip    : %s\n"
2699     			" Address: 0x%08lX\n"
2700     			" IRQ    : %d\n"
2701     			" DMA    : %d\n",
2702     			info->scsi.type, info->host->io_port,
2703     			info->host->irq, info->host->dma_channel);
2704     }
2705     
2706     int fas216_print_stats(FAS216_Info *info, char *buffer)
2707     {
2708     	return sprintf(buffer,
2709     			"\n"
2710     			"Command Statistics:\n"
2711     			" Queued     : %u\n"
2712     			" Issued     : %u\n"
2713     			" Completed  : %u\n"
2714     			" Reads      : %u\n"
2715     			" Writes     : %u\n"
2716     			" Others     : %u\n"
2717     			" Disconnects: %u\n"
2718     			" Aborts     : %u\n"
2719     			" Bus resets : %u\n"
2720     			" Host resets: %u\n",
2721     			info->stats.queues,	 info->stats.removes,
2722     			info->stats.fins,	 info->stats.reads,
2723     			info->stats.writes,	 info->stats.miscs,
2724     			info->stats.disconnects, info->stats.aborts,
2725     			info->stats.bus_resets,	 info->stats.host_resets);
2726     }
2727     
2728     int fas216_print_device(FAS216_Info *info, Scsi_Device *scd, char *buffer)
2729     {
2730     	struct fas216_device *dev = &info->device[scd->id];
2731     	int len = 0;
2732     	char *p;
2733     
2734     	proc_print_scsidevice(scd, buffer, &len, 0);
2735     	p = buffer + len;
2736     
2737     	p += sprintf(p, "  Extensions: ");
2738     
2739     	if (scd->tagged_supported)
2740     		p += sprintf(p, "TAG %sabled [%d] ",
2741     			     scd->tagged_queue ? "en" : "dis",
2742     			     scd->current_tag);
2743     
2744     	p += sprintf(p, "\n  Transfers : %d-bit ",
2745     		     8 << dev->wide_xfer);
2746     
2747     	if (dev->sof)
2748     		p += sprintf(p, "sync offset %d, %d ns\n",
2749     				dev->sof, dev->period * 4);
2750     	else
2751     		p += sprintf(p, "async\n");
2752     
2753     	return p - buffer;
2754     }
2755     
2756     EXPORT_SYMBOL(fas216_info);
2757     EXPORT_SYMBOL(fas216_init);
2758     EXPORT_SYMBOL(fas216_queue_command);
2759     EXPORT_SYMBOL(fas216_command);
2760     EXPORT_SYMBOL(fas216_intr);
2761     EXPORT_SYMBOL(fas216_release);
2762     EXPORT_SYMBOL(fas216_eh_abort);
2763     EXPORT_SYMBOL(fas216_eh_device_reset);
2764     EXPORT_SYMBOL(fas216_eh_bus_reset);
2765     EXPORT_SYMBOL(fas216_eh_host_reset);
2766     EXPORT_SYMBOL(fas216_print_host);
2767     EXPORT_SYMBOL(fas216_print_stats);
2768     EXPORT_SYMBOL(fas216_print_device);
2769     
2770     #ifdef MODULE
2771     int __init init_module(void)
2772     {
2773     	return 0;
2774     }
2775     
2776     void __exit cleanup_module(void)
2777     {
2778     }
2779     #endif
2780     
2781     MODULE_LICENSE("GPL");
2782