xref: /openbmc/linux/drivers/scsi/arm/acornscsi.c (revision b34e08d5)
1 /*
2  *  linux/drivers/acorn/scsi/acornscsi.c
3  *
4  *  Acorn SCSI 3 driver
5  *  By R.M.King.
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License version 2 as
9  * published by the Free Software Foundation.
10  *
11  * Abandoned using the Select and Transfer command since there were
12  * some nasty races between our software and the target devices that
13  * were not easy to solve, and the device errata had a lot of entries
14  * for this command, some of them quite nasty...
15  *
16  * Changelog:
17  *  26-Sep-1997	RMK	Re-jigged to use the queue module.
18  *			Re-coded state machine to be based on driver
19  *			state not scsi state.  Should be easier to debug.
20  *			Added acornscsi_release to clean up properly.
21  *			Updated proc/scsi reporting.
22  *  05-Oct-1997	RMK	Implemented writing to SCSI devices.
23  *  06-Oct-1997	RMK	Corrected small (non-serious) bug with the connect/
24  *			reconnect race condition causing a warning message.
25  *  12-Oct-1997	RMK	Added catch for re-entering interrupt routine.
26  *  15-Oct-1997	RMK	Improved handling of commands.
27  *  27-Jun-1998	RMK	Changed asm/delay.h to linux/delay.h.
28  *  13-Dec-1998	RMK	Better abort code and command handling.  Extra state
29  *			transitions added to allow dodgy devices to work.
30  */
31 #define DEBUG_NO_WRITE	1
32 #define DEBUG_QUEUES	2
33 #define DEBUG_DMA	4
34 #define DEBUG_ABORT	8
35 #define DEBUG_DISCON	16
36 #define DEBUG_CONNECT	32
37 #define DEBUG_PHASES	64
38 #define DEBUG_WRITE	128
39 #define DEBUG_LINK	256
40 #define DEBUG_MESSAGES	512
41 #define DEBUG_RESET	1024
42 #define DEBUG_ALL	(DEBUG_RESET|DEBUG_MESSAGES|DEBUG_LINK|DEBUG_WRITE|\
43 			 DEBUG_PHASES|DEBUG_CONNECT|DEBUG_DISCON|DEBUG_ABORT|\
44 			 DEBUG_DMA|DEBUG_QUEUES)
45 
46 /* DRIVER CONFIGURATION
47  *
48  * SCSI-II Tagged queue support.
49  *
50  * I don't have any SCSI devices that support it, so it is totally untested
51  * (except to make sure that it doesn't interfere with any non-tagging
52  * devices).  It is not fully implemented either - what happens when a
53  * tagging device reconnects???
54  *
55  * You can tell if you have a device that supports tagged queueing my
56  * cating (eg) /proc/scsi/acornscsi/0 and see if the SCSI revision is reported
57  * as '2 TAG'.
58  *
59  * Also note that CONFIG_SCSI_ACORNSCSI_TAGGED_QUEUE is normally set in the config
60  * scripts, but disabled here.  Once debugged, remove the #undef, otherwise to debug,
61  * comment out the undef.
62  */
63 #undef CONFIG_SCSI_ACORNSCSI_TAGGED_QUEUE
64 /*
65  * SCSI-II Linked command support.
66  *
67  * The higher level code doesn't support linked commands yet, and so the option
68  * is undef'd here.
69  */
70 #undef CONFIG_SCSI_ACORNSCSI_LINK
71 /*
72  * SCSI-II Synchronous transfer support.
73  *
74  * Tried and tested...
75  *
76  * SDTR_SIZE	  - maximum number of un-acknowledged bytes (0 = off, 12 = max)
77  * SDTR_PERIOD	  - period of REQ signal (min=125, max=1020)
78  * DEFAULT_PERIOD - default REQ period.
79  */
80 #define SDTR_SIZE	12
81 #define SDTR_PERIOD	125
82 #define DEFAULT_PERIOD	500
83 
84 /*
85  * Debugging information
86  *
87  * DEBUG	  - bit mask from list above
88  * DEBUG_TARGET   - is defined to the target number if you want to debug
89  *		    a specific target. [only recon/write/dma].
90  */
91 #define DEBUG (DEBUG_RESET|DEBUG_WRITE|DEBUG_NO_WRITE)
92 /* only allow writing to SCSI device 0 */
93 #define NO_WRITE 0xFE
94 /*#define DEBUG_TARGET 2*/
95 /*
96  * Select timeout time (in 10ms units)
97  *
98  * This is the timeout used between the start of selection and the WD33C93
99  * chip deciding that the device isn't responding.
100  */
101 #define TIMEOUT_TIME 10
102 /*
103  * Define this if you want to have verbose explanation of SCSI
104  * status/messages.
105  */
106 #undef CONFIG_ACORNSCSI_CONSTANTS
107 /*
108  * Define this if you want to use the on board DMAC [don't remove this option]
109  * If not set, then use PIO mode (not currently supported).
110  */
111 #define USE_DMAC
112 
113 /*
114  * ====================================================================================
115  */
116 
117 #ifdef DEBUG_TARGET
118 #define DBG(cmd,xxx...) \
119   if (cmd->device->id == DEBUG_TARGET) { \
120     xxx; \
121   }
122 #else
123 #define DBG(cmd,xxx...) xxx
124 #endif
125 
126 #include <linux/module.h>
127 #include <linux/kernel.h>
128 #include <linux/string.h>
129 #include <linux/signal.h>
130 #include <linux/errno.h>
131 #include <linux/proc_fs.h>
132 #include <linux/ioport.h>
133 #include <linux/blkdev.h>
134 #include <linux/delay.h>
135 #include <linux/interrupt.h>
136 #include <linux/init.h>
137 #include <linux/bitops.h>
138 #include <linux/stringify.h>
139 #include <linux/io.h>
140 
141 #include <asm/ecard.h>
142 
143 #include "../scsi.h"
144 #include <scsi/scsi_dbg.h>
145 #include <scsi/scsi_host.h>
146 #include <scsi/scsi_transport_spi.h>
147 #include "acornscsi.h"
148 #include "msgqueue.h"
149 #include "scsi.h"
150 
151 #include <scsi/scsicam.h>
152 
153 #define VER_MAJOR 2
154 #define VER_MINOR 0
155 #define VER_PATCH 6
156 
157 #ifndef ABORT_TAG
158 #define ABORT_TAG 0xd
159 #else
160 #error "Yippee!  ABORT TAG is now defined!  Remove this error!"
161 #endif
162 
163 #ifdef CONFIG_SCSI_ACORNSCSI_LINK
164 #error SCSI2 LINKed commands not supported (yet)!
165 #endif
166 
167 #ifdef USE_DMAC
168 /*
169  * DMAC setup parameters
170  */
171 #define INIT_DEVCON0	(DEVCON0_RQL|DEVCON0_EXW|DEVCON0_CMP)
172 #define INIT_DEVCON1	(DEVCON1_BHLD)
173 #define DMAC_READ	(MODECON_READ)
174 #define DMAC_WRITE	(MODECON_WRITE)
175 #define INIT_SBICDMA	(CTRL_DMABURST)
176 
177 #define scsi_xferred	have_data_in
178 
179 /*
180  * Size of on-board DMA buffer
181  */
182 #define DMAC_BUFFER_SIZE	65536
183 #endif
184 
185 #define STATUS_BUFFER_TO_PRINT	24
186 
187 unsigned int sdtr_period = SDTR_PERIOD;
188 unsigned int sdtr_size   = SDTR_SIZE;
189 
190 static void acornscsi_done(AS_Host *host, struct scsi_cmnd **SCpntp,
191 			   unsigned int result);
192 static int acornscsi_reconnect_finish(AS_Host *host);
193 static void acornscsi_dma_cleanup(AS_Host *host);
194 static void acornscsi_abortcmd(AS_Host *host, unsigned char tag);
195 
196 /* ====================================================================================
197  * Miscellaneous
198  */
199 
200 /* Offsets from MEMC base */
201 #define SBIC_REGIDX	0x2000
202 #define SBIC_REGVAL	0x2004
203 #define DMAC_OFFSET	0x3000
204 
205 /* Offsets from FAST IOC base */
206 #define INT_REG		0x2000
207 #define PAGE_REG	0x3000
208 
209 static inline void sbic_arm_write(AS_Host *host, unsigned int reg, unsigned int value)
210 {
211     writeb(reg, host->base + SBIC_REGIDX);
212     writeb(value, host->base + SBIC_REGVAL);
213 }
214 
215 static inline int sbic_arm_read(AS_Host *host, unsigned int reg)
216 {
217     if(reg == SBIC_ASR)
218 	   return readl(host->base + SBIC_REGIDX) & 255;
219     writeb(reg, host->base + SBIC_REGIDX);
220     return readl(host->base + SBIC_REGVAL) & 255;
221 }
222 
223 #define sbic_arm_writenext(host, val)	writeb((val), (host)->base + SBIC_REGVAL)
224 #define sbic_arm_readnext(host) 	readb((host)->base + SBIC_REGVAL)
225 
226 #ifdef USE_DMAC
227 #define dmac_read(host,reg) \
228 	readb((host)->base + DMAC_OFFSET + ((reg) << 2))
229 
230 #define dmac_write(host,reg,value) \
231 	({ writeb((value), (host)->base + DMAC_OFFSET + ((reg) << 2)); })
232 
233 #define dmac_clearintr(host) 	writeb(0, (host)->fast + INT_REG)
234 
235 static inline unsigned int dmac_address(AS_Host *host)
236 {
237     return dmac_read(host, DMAC_TXADRHI) << 16 |
238 	   dmac_read(host, DMAC_TXADRMD) << 8 |
239 	   dmac_read(host, DMAC_TXADRLO);
240 }
241 
242 static
243 void acornscsi_dumpdma(AS_Host *host, char *where)
244 {
245 	unsigned int mode, addr, len;
246 
247 	mode = dmac_read(host, DMAC_MODECON);
248 	addr = dmac_address(host);
249 	len  = dmac_read(host, DMAC_TXCNTHI) << 8 |
250 	       dmac_read(host, DMAC_TXCNTLO);
251 
252 	printk("scsi%d: %s: DMAC %02x @%06x+%04x msk %02x, ",
253 		host->host->host_no, where,
254 		mode, addr, (len + 1) & 0xffff,
255 		dmac_read(host, DMAC_MASKREG));
256 
257 	printk("DMA @%06x, ", host->dma.start_addr);
258 	printk("BH @%p +%04x, ", host->scsi.SCp.ptr,
259 		host->scsi.SCp.this_residual);
260 	printk("DT @+%04x ST @+%04x", host->dma.transferred,
261 		host->scsi.SCp.scsi_xferred);
262 	printk("\n");
263 }
264 #endif
265 
266 static
267 unsigned long acornscsi_sbic_xfcount(AS_Host *host)
268 {
269     unsigned long length;
270 
271     length = sbic_arm_read(host, SBIC_TRANSCNTH) << 16;
272     length |= sbic_arm_readnext(host) << 8;
273     length |= sbic_arm_readnext(host);
274 
275     return length;
276 }
277 
278 static int
279 acornscsi_sbic_wait(AS_Host *host, int stat_mask, int stat, int timeout, char *msg)
280 {
281 	int asr;
282 
283 	do {
284 		asr = sbic_arm_read(host, SBIC_ASR);
285 
286 		if ((asr & stat_mask) == stat)
287 			return 0;
288 
289 		udelay(1);
290 	} while (--timeout);
291 
292 	printk("scsi%d: timeout while %s\n", host->host->host_no, msg);
293 
294 	return -1;
295 }
296 
297 static
298 int acornscsi_sbic_issuecmd(AS_Host *host, int command)
299 {
300     if (acornscsi_sbic_wait(host, ASR_CIP, 0, 1000, "issuing command"))
301 	return -1;
302 
303     sbic_arm_write(host, SBIC_CMND, command);
304 
305     return 0;
306 }
307 
308 static void
309 acornscsi_csdelay(unsigned int cs)
310 {
311     unsigned long target_jiffies, flags;
312 
313     target_jiffies = jiffies + 1 + cs * HZ / 100;
314 
315     local_save_flags(flags);
316     local_irq_enable();
317 
318     while (time_before(jiffies, target_jiffies)) barrier();
319 
320     local_irq_restore(flags);
321 }
322 
323 static
324 void acornscsi_resetcard(AS_Host *host)
325 {
326     unsigned int i, timeout;
327 
328     /* assert reset line */
329     host->card.page_reg = 0x80;
330     writeb(host->card.page_reg, host->fast + PAGE_REG);
331 
332     /* wait 3 cs.  SCSI standard says 25ms. */
333     acornscsi_csdelay(3);
334 
335     host->card.page_reg = 0;
336     writeb(host->card.page_reg, host->fast + PAGE_REG);
337 
338     /*
339      * Should get a reset from the card
340      */
341     timeout = 1000;
342     do {
343 	if (readb(host->fast + INT_REG) & 8)
344 	    break;
345 	udelay(1);
346     } while (--timeout);
347 
348     if (timeout == 0)
349 	printk("scsi%d: timeout while resetting card\n",
350 		host->host->host_no);
351 
352     sbic_arm_read(host, SBIC_ASR);
353     sbic_arm_read(host, SBIC_SSR);
354 
355     /* setup sbic - WD33C93A */
356     sbic_arm_write(host, SBIC_OWNID, OWNID_EAF | host->host->this_id);
357     sbic_arm_write(host, SBIC_CMND, CMND_RESET);
358 
359     /*
360      * Command should cause a reset interrupt
361      */
362     timeout = 1000;
363     do {
364 	if (readb(host->fast + INT_REG) & 8)
365 	    break;
366 	udelay(1);
367     } while (--timeout);
368 
369     if (timeout == 0)
370 	printk("scsi%d: timeout while resetting card\n",
371 		host->host->host_no);
372 
373     sbic_arm_read(host, SBIC_ASR);
374     if (sbic_arm_read(host, SBIC_SSR) != 0x01)
375 	printk(KERN_CRIT "scsi%d: WD33C93A didn't give enhanced reset interrupt\n",
376 		host->host->host_no);
377 
378     sbic_arm_write(host, SBIC_CTRL, INIT_SBICDMA | CTRL_IDI);
379     sbic_arm_write(host, SBIC_TIMEOUT, TIMEOUT_TIME);
380     sbic_arm_write(host, SBIC_SYNCHTRANSFER, SYNCHTRANSFER_2DBA);
381     sbic_arm_write(host, SBIC_SOURCEID, SOURCEID_ER | SOURCEID_DSP);
382 
383     host->card.page_reg = 0x40;
384     writeb(host->card.page_reg, host->fast + PAGE_REG);
385 
386     /* setup dmac - uPC71071 */
387     dmac_write(host, DMAC_INIT, 0);
388 #ifdef USE_DMAC
389     dmac_write(host, DMAC_INIT, INIT_8BIT);
390     dmac_write(host, DMAC_CHANNEL, CHANNEL_0);
391     dmac_write(host, DMAC_DEVCON0, INIT_DEVCON0);
392     dmac_write(host, DMAC_DEVCON1, INIT_DEVCON1);
393 #endif
394 
395     host->SCpnt = NULL;
396     host->scsi.phase = PHASE_IDLE;
397     host->scsi.disconnectable = 0;
398 
399     memset(host->busyluns, 0, sizeof(host->busyluns));
400 
401     for (i = 0; i < 8; i++) {
402 	host->device[i].sync_state = SYNC_NEGOCIATE;
403 	host->device[i].disconnect_ok = 1;
404     }
405 
406     /* wait 25 cs.  SCSI standard says 250ms. */
407     acornscsi_csdelay(25);
408 }
409 
410 /*=============================================================================================
411  * Utility routines (eg. debug)
412  */
413 #ifdef CONFIG_ACORNSCSI_CONSTANTS
414 static char *acornscsi_interrupttype[] = {
415   "rst",  "suc",  "p/a",  "3",
416   "term", "5",	  "6",	  "7",
417   "serv", "9",	  "a",	  "b",
418   "c",	  "d",	  "e",	  "f"
419 };
420 
421 static signed char acornscsi_map[] = {
422   0,  1, -1, -1,  -1, -1, -1, -1,  -1, -1, -1, -1,  -1, -1, -1, -1,
423  -1,  2, -1, -1,  -1, -1,  3, -1,   4,	5,  6,	7,   8,  9, 10, 11,
424  12, 13, 14, -1,  -1, -1, -1, -1,   4,	5,  6,	7,   8,  9, 10, 11,
425  -1, -1, -1, -1,  -1, -1, -1, -1,  -1, -1, -1, -1,  -1, -1, -1, -1,
426  15, 16, 17, 18,  19, -1, -1, 20,   4,	5,  6,	7,   8,  9, 10, 11,
427  -1, -1, -1, -1,  -1, -1, -1, -1,  -1, -1, -1, -1,  -1, -1, -1, -1,
428  -1, -1, -1, -1,  -1, -1, -1, -1,  -1, -1, -1, -1,  -1, -1, -1, -1,
429  -1, -1, -1, -1,  -1, -1, -1, -1,  -1, -1, -1, -1,  -1, -1, -1, -1,
430  21, 22, -1, -1,  -1, 23, -1, -1,   4,	5,  6,	7,   8,  9, 10, 11,
431  -1, -1, -1, -1,  -1, -1, -1, -1,  -1, -1, -1, -1,  -1, -1, -1, -1,
432  -1, -1, -1, -1,  -1, -1, -1, -1,  -1, -1, -1, -1,  -1, -1, -1, -1,
433  -1, -1, -1, -1,  -1, -1, -1, -1,  -1, -1, -1, -1,  -1, -1, -1, -1,
434  -1, -1, -1, -1,  -1, -1, -1, -1,  -1, -1, -1, -1,  -1, -1, -1, -1,
435  -1, -1, -1, -1,  -1, -1, -1, -1,  -1, -1, -1, -1,  -1, -1, -1, -1,
436  -1, -1, -1, -1,  -1, -1, -1, -1,  -1, -1, -1, -1,  -1, -1, -1, -1,
437  -1, -1, -1, -1,  -1, -1, -1, -1,  -1, -1, -1, -1,  -1, -1, -1, -1
438 };
439 
440 static char *acornscsi_interruptcode[] = {
441     /* 0 */
442     "reset - normal mode",	/* 00 */
443     "reset - advanced mode",	/* 01 */
444 
445     /* 2 */
446     "sel",			/* 11 */
447     "sel+xfer", 		/* 16 */
448     "data-out", 		/* 18 */
449     "data-in",			/* 19 */
450     "cmd",			/* 1A */
451     "stat",			/* 1B */
452     "??-out",			/* 1C */
453     "??-in",			/* 1D */
454     "msg-out",			/* 1E */
455     "msg-in",			/* 1F */
456 
457     /* 12 */
458     "/ACK asserted",		/* 20 */
459     "save-data-ptr",		/* 21 */
460     "{re}sel",			/* 22 */
461 
462     /* 15 */
463     "inv cmd",			/* 40 */
464     "unexpected disconnect",	/* 41 */
465     "sel timeout",		/* 42 */
466     "P err",			/* 43 */
467     "P err+ATN",		/* 44 */
468     "bad status byte",		/* 47 */
469 
470     /* 21 */
471     "resel, no id",		/* 80 */
472     "resel",			/* 81 */
473     "discon",			/* 85 */
474 };
475 
476 static
477 void print_scsi_status(unsigned int ssr)
478 {
479     if (acornscsi_map[ssr] != -1)
480 	printk("%s:%s",
481 		acornscsi_interrupttype[(ssr >> 4)],
482 		acornscsi_interruptcode[acornscsi_map[ssr]]);
483     else
484 	printk("%X:%X", ssr >> 4, ssr & 0x0f);
485 }
486 #endif
487 
488 static
489 void print_sbic_status(int asr, int ssr, int cmdphase)
490 {
491 #ifdef CONFIG_ACORNSCSI_CONSTANTS
492     printk("sbic: %c%c%c%c%c%c ",
493 	    asr & ASR_INT ? 'I' : 'i',
494 	    asr & ASR_LCI ? 'L' : 'l',
495 	    asr & ASR_BSY ? 'B' : 'b',
496 	    asr & ASR_CIP ? 'C' : 'c',
497 	    asr & ASR_PE  ? 'P' : 'p',
498 	    asr & ASR_DBR ? 'D' : 'd');
499     printk("scsi: ");
500     print_scsi_status(ssr);
501     printk(" ph %02X\n", cmdphase);
502 #else
503     printk("sbic: %02X scsi: %X:%X ph: %02X\n",
504 	    asr, (ssr & 0xf0)>>4, ssr & 0x0f, cmdphase);
505 #endif
506 }
507 
508 static void
509 acornscsi_dumplogline(AS_Host *host, int target, int line)
510 {
511 	unsigned long prev;
512 	signed int ptr;
513 
514 	ptr = host->status_ptr[target] - STATUS_BUFFER_TO_PRINT;
515 	if (ptr < 0)
516 		ptr += STATUS_BUFFER_SIZE;
517 
518 	printk("%c: %3s:", target == 8 ? 'H' : '0' + target,
519 		line == 0 ? "ph" : line == 1 ? "ssr" : "int");
520 
521 	prev = host->status[target][ptr].when;
522 
523 	for (; ptr != host->status_ptr[target]; ptr = (ptr + 1) & (STATUS_BUFFER_SIZE - 1)) {
524 		unsigned long time_diff;
525 
526 		if (!host->status[target][ptr].when)
527 			continue;
528 
529 		switch (line) {
530 		case 0:
531 			printk("%c%02X", host->status[target][ptr].irq ? '-' : ' ',
532 					 host->status[target][ptr].ph);
533 			break;
534 
535 		case 1:
536 			printk(" %02X", host->status[target][ptr].ssr);
537 			break;
538 
539 		case 2:
540 			time_diff = host->status[target][ptr].when - prev;
541 			prev = host->status[target][ptr].when;
542 			if (time_diff == 0)
543 				printk("==^");
544 			else if (time_diff >= 100)
545 				printk("   ");
546 			else
547 				printk(" %02ld", time_diff);
548 			break;
549 		}
550 	}
551 
552 	printk("\n");
553 }
554 
555 static
556 void acornscsi_dumplog(AS_Host *host, int target)
557 {
558     do {
559 	acornscsi_dumplogline(host, target, 0);
560 	acornscsi_dumplogline(host, target, 1);
561 	acornscsi_dumplogline(host, target, 2);
562 
563 	if (target == 8)
564 	    break;
565 
566 	target = 8;
567     } while (1);
568 }
569 
570 static
571 char acornscsi_target(AS_Host *host)
572 {
573 	if (host->SCpnt)
574 		return '0' + host->SCpnt->device->id;
575 	return 'H';
576 }
577 
578 /*
579  * Prototype: cmdtype_t acornscsi_cmdtype(int command)
580  * Purpose  : differentiate READ from WRITE from other commands
581  * Params   : command - command to interpret
582  * Returns  : CMD_READ	- command reads data,
583  *	      CMD_WRITE - command writes data,
584  *	      CMD_MISC	- everything else
585  */
586 static inline
587 cmdtype_t acornscsi_cmdtype(int command)
588 {
589     switch (command) {
590     case WRITE_6:  case WRITE_10:  case WRITE_12:
591 	return CMD_WRITE;
592     case READ_6:   case READ_10:   case READ_12:
593 	return CMD_READ;
594     default:
595 	return CMD_MISC;
596     }
597 }
598 
599 /*
600  * Prototype: int acornscsi_datadirection(int command)
601  * Purpose  : differentiate between commands that have a DATA IN phase
602  *	      and a DATA OUT phase
603  * Params   : command - command to interpret
604  * Returns  : DATADIR_OUT - data out phase expected
605  *	      DATADIR_IN  - data in phase expected
606  */
607 static
608 datadir_t acornscsi_datadirection(int command)
609 {
610     switch (command) {
611     case CHANGE_DEFINITION:	case COMPARE:		case COPY:
612     case COPY_VERIFY:		case LOG_SELECT:	case MODE_SELECT:
613     case MODE_SELECT_10:	case SEND_DIAGNOSTIC:	case WRITE_BUFFER:
614     case FORMAT_UNIT:		case REASSIGN_BLOCKS:	case RESERVE:
615     case SEARCH_EQUAL:		case SEARCH_HIGH:	case SEARCH_LOW:
616     case WRITE_6:		case WRITE_10:		case WRITE_VERIFY:
617     case UPDATE_BLOCK:		case WRITE_LONG:	case WRITE_SAME:
618     case SEARCH_HIGH_12:	case SEARCH_EQUAL_12:	case SEARCH_LOW_12:
619     case WRITE_12:		case WRITE_VERIFY_12:	case SET_WINDOW:
620     case MEDIUM_SCAN:		case SEND_VOLUME_TAG:	case 0xea:
621 	return DATADIR_OUT;
622     default:
623 	return DATADIR_IN;
624     }
625 }
626 
627 /*
628  * Purpose  : provide values for synchronous transfers with 33C93.
629  * Copyright: Copyright (c) 1996 John Shifflett, GeoLog Consulting
630  *	Modified by Russell King for 8MHz WD33C93A
631  */
632 static struct sync_xfer_tbl {
633     unsigned int period_ns;
634     unsigned char reg_value;
635 } sync_xfer_table[] = {
636     {	1, 0x20 },    { 249, 0x20 },	{ 374, 0x30 },
637     { 499, 0x40 },    { 624, 0x50 },	{ 749, 0x60 },
638     { 874, 0x70 },    { 999, 0x00 },	{   0,	  0 }
639 };
640 
641 /*
642  * Prototype: int acornscsi_getperiod(unsigned char syncxfer)
643  * Purpose  : period for the synchronous transfer setting
644  * Params   : syncxfer SYNCXFER register value
645  * Returns  : period in ns.
646  */
647 static
648 int acornscsi_getperiod(unsigned char syncxfer)
649 {
650     int i;
651 
652     syncxfer &= 0xf0;
653     if (syncxfer == 0x10)
654 	syncxfer = 0;
655 
656     for (i = 1; sync_xfer_table[i].period_ns; i++)
657 	if (syncxfer == sync_xfer_table[i].reg_value)
658 	    return sync_xfer_table[i].period_ns;
659     return 0;
660 }
661 
662 /*
663  * Prototype: int round_period(unsigned int period)
664  * Purpose  : return index into above table for a required REQ period
665  * Params   : period - time (ns) for REQ
666  * Returns  : table index
667  * Copyright: Copyright (c) 1996 John Shifflett, GeoLog Consulting
668  */
669 static inline
670 int round_period(unsigned int period)
671 {
672     int i;
673 
674     for (i = 1; sync_xfer_table[i].period_ns; i++) {
675 	if ((period <= sync_xfer_table[i].period_ns) &&
676 	    (period > sync_xfer_table[i - 1].period_ns))
677 	    return i;
678     }
679     return 7;
680 }
681 
682 /*
683  * Prototype: unsigned char calc_sync_xfer(unsigned int period, unsigned int offset)
684  * Purpose  : calculate value for 33c93s SYNC register
685  * Params   : period - time (ns) for REQ
686  *	      offset - offset in bytes between REQ/ACK
687  * Returns  : value for SYNC register
688  * Copyright: Copyright (c) 1996 John Shifflett, GeoLog Consulting
689  */
690 static
691 unsigned char calc_sync_xfer(unsigned int period, unsigned int offset)
692 {
693     return sync_xfer_table[round_period(period)].reg_value |
694 		((offset < SDTR_SIZE) ? offset : SDTR_SIZE);
695 }
696 
697 /* ====================================================================================
698  * Command functions
699  */
700 /*
701  * Function: acornscsi_kick(AS_Host *host)
702  * Purpose : kick next command to interface
703  * Params  : host - host to send command to
704  * Returns : INTR_IDLE if idle, otherwise INTR_PROCESSING
705  * Notes   : interrupts are always disabled!
706  */
707 static
708 intr_ret_t acornscsi_kick(AS_Host *host)
709 {
710     int from_queue = 0;
711     struct scsi_cmnd *SCpnt;
712 
713     /* first check to see if a command is waiting to be executed */
714     SCpnt = host->origSCpnt;
715     host->origSCpnt = NULL;
716 
717     /* retrieve next command */
718     if (!SCpnt) {
719 	SCpnt = queue_remove_exclude(&host->queues.issue, host->busyluns);
720 	if (!SCpnt)
721 	    return INTR_IDLE;
722 
723 	from_queue = 1;
724     }
725 
726     if (host->scsi.disconnectable && host->SCpnt) {
727 	queue_add_cmd_tail(&host->queues.disconnected, host->SCpnt);
728 	host->scsi.disconnectable = 0;
729 #if (DEBUG & (DEBUG_QUEUES|DEBUG_DISCON))
730 	DBG(host->SCpnt, printk("scsi%d.%c: moved command to disconnected queue\n",
731 		host->host->host_no, acornscsi_target(host)));
732 #endif
733 	host->SCpnt = NULL;
734     }
735 
736     /*
737      * If we have an interrupt pending, then we may have been reselected.
738      * In this case, we don't want to write to the registers
739      */
740     if (!(sbic_arm_read(host, SBIC_ASR) & (ASR_INT|ASR_BSY|ASR_CIP))) {
741 	sbic_arm_write(host, SBIC_DESTID, SCpnt->device->id);
742 	sbic_arm_write(host, SBIC_CMND, CMND_SELWITHATN);
743     }
744 
745     /*
746      * claim host busy - all of these must happen atomically wrt
747      * our interrupt routine.  Failure means command loss.
748      */
749     host->scsi.phase = PHASE_CONNECTING;
750     host->SCpnt = SCpnt;
751     host->scsi.SCp = SCpnt->SCp;
752     host->dma.xfer_setup = 0;
753     host->dma.xfer_required = 0;
754     host->dma.xfer_done = 0;
755 
756 #if (DEBUG & (DEBUG_ABORT|DEBUG_CONNECT))
757     DBG(SCpnt,printk("scsi%d.%c: starting cmd %02X\n",
758 	    host->host->host_no, '0' + SCpnt->device->id,
759 	    SCpnt->cmnd[0]));
760 #endif
761 
762     if (from_queue) {
763 #ifdef CONFIG_SCSI_ACORNSCSI_TAGGED_QUEUE
764 	/*
765 	 * tagged queueing - allocate a new tag to this command
766 	 */
767 	if (SCpnt->device->simple_tags) {
768 	    SCpnt->device->current_tag += 1;
769 	    if (SCpnt->device->current_tag == 0)
770 		SCpnt->device->current_tag = 1;
771 	    SCpnt->tag = SCpnt->device->current_tag;
772 	} else
773 #endif
774 	    set_bit(SCpnt->device->id * 8 + SCpnt->device->lun, host->busyluns);
775 
776 	host->stats.removes += 1;
777 
778 	switch (acornscsi_cmdtype(SCpnt->cmnd[0])) {
779 	case CMD_WRITE:
780 	    host->stats.writes += 1;
781 	    break;
782 	case CMD_READ:
783 	    host->stats.reads += 1;
784 	    break;
785 	case CMD_MISC:
786 	    host->stats.miscs += 1;
787 	    break;
788 	}
789     }
790 
791     return INTR_PROCESSING;
792 }
793 
794 /*
795  * Function: void acornscsi_done(AS_Host *host, struct scsi_cmnd **SCpntp, unsigned int result)
796  * Purpose : complete processing for command
797  * Params  : host   - interface that completed
798  *	     result - driver byte of result
799  */
800 static void acornscsi_done(AS_Host *host, struct scsi_cmnd **SCpntp,
801 			   unsigned int result)
802 {
803 	struct scsi_cmnd *SCpnt = *SCpntp;
804 
805     /* clean up */
806     sbic_arm_write(host, SBIC_SOURCEID, SOURCEID_ER | SOURCEID_DSP);
807 
808     host->stats.fins += 1;
809 
810     if (SCpnt) {
811 	*SCpntp = NULL;
812 
813 	acornscsi_dma_cleanup(host);
814 
815 	SCpnt->result = result << 16 | host->scsi.SCp.Message << 8 | host->scsi.SCp.Status;
816 
817 	/*
818 	 * In theory, this should not happen.  In practice, it seems to.
819 	 * Only trigger an error if the device attempts to report all happy
820 	 * but with untransferred buffers...  If we don't do something, then
821 	 * data loss will occur.  Should we check SCpnt->underflow here?
822 	 * It doesn't appear to be set to something meaningful by the higher
823 	 * levels all the time.
824 	 */
825 	if (result == DID_OK) {
826 		int xfer_warn = 0;
827 
828 		if (SCpnt->underflow == 0) {
829 			if (host->scsi.SCp.ptr &&
830 			    acornscsi_cmdtype(SCpnt->cmnd[0]) != CMD_MISC)
831 				xfer_warn = 1;
832 		} else {
833 			if (host->scsi.SCp.scsi_xferred < SCpnt->underflow ||
834 			    host->scsi.SCp.scsi_xferred != host->dma.transferred)
835 				xfer_warn = 1;
836 		}
837 
838 		/* ANSI standard says: (SCSI-2 Rev 10c Sect 5.6.6)
839 		 *  Targets which break data transfers into multiple
840 		 *  connections shall end each successful connection
841 		 *  (except possibly the last) with a SAVE DATA
842 		 *  POINTER - DISCONNECT message sequence.
843 		 *
844 		 * This makes it difficult to ensure that a transfer has
845 		 * completed.  If we reach the end of a transfer during
846 		 * the command, then we can only have finished the transfer.
847 		 * therefore, if we seem to have some data remaining, this
848 		 * is not a problem.
849 		 */
850 		if (host->dma.xfer_done)
851 			xfer_warn = 0;
852 
853 		if (xfer_warn) {
854 		    switch (status_byte(SCpnt->result)) {
855 		    case CHECK_CONDITION:
856 		    case COMMAND_TERMINATED:
857 		    case BUSY:
858 		    case QUEUE_FULL:
859 		    case RESERVATION_CONFLICT:
860 			break;
861 
862 		    default:
863 			printk(KERN_ERR "scsi%d.H: incomplete data transfer detected: result=%08X command=",
864 				host->host->host_no, SCpnt->result);
865 			__scsi_print_command(SCpnt->cmnd);
866 			acornscsi_dumpdma(host, "done");
867 		 	acornscsi_dumplog(host, SCpnt->device->id);
868 			SCpnt->result &= 0xffff;
869 			SCpnt->result |= DID_ERROR << 16;
870 		    }
871 		}
872 	}
873 
874 	if (!SCpnt->scsi_done)
875 	    panic("scsi%d.H: null scsi_done function in acornscsi_done", host->host->host_no);
876 
877 	clear_bit(SCpnt->device->id * 8 + SCpnt->device->lun, host->busyluns);
878 
879 	SCpnt->scsi_done(SCpnt);
880     } else
881 	printk("scsi%d: null command in acornscsi_done", host->host->host_no);
882 
883     host->scsi.phase = PHASE_IDLE;
884 }
885 
886 /* ====================================================================================
887  * DMA routines
888  */
889 /*
890  * Purpose  : update SCSI Data Pointer
891  * Notes    : this will only be one SG entry or less
892  */
893 static
894 void acornscsi_data_updateptr(AS_Host *host, struct scsi_pointer *SCp, unsigned int length)
895 {
896     SCp->ptr += length;
897     SCp->this_residual -= length;
898 
899     if (SCp->this_residual == 0 && next_SCp(SCp) == 0)
900 	host->dma.xfer_done = 1;
901 }
902 
903 /*
904  * Prototype: void acornscsi_data_read(AS_Host *host, char *ptr,
905  *				unsigned int start_addr, unsigned int length)
906  * Purpose  : read data from DMA RAM
907  * Params   : host - host to transfer from
908  *	      ptr  - DRAM address
909  *	      start_addr - host mem address
910  *	      length - number of bytes to transfer
911  * Notes    : this will only be one SG entry or less
912  */
913 static
914 void acornscsi_data_read(AS_Host *host, char *ptr,
915 				 unsigned int start_addr, unsigned int length)
916 {
917     extern void __acornscsi_in(void __iomem *, char *buf, int len);
918     unsigned int page, offset, len = length;
919 
920     page = (start_addr >> 12);
921     offset = start_addr & ((1 << 12) - 1);
922 
923     writeb((page & 0x3f) | host->card.page_reg, host->fast + PAGE_REG);
924 
925     while (len > 0) {
926 	unsigned int this_len;
927 
928 	if (len + offset > (1 << 12))
929 	    this_len = (1 << 12) - offset;
930 	else
931 	    this_len = len;
932 
933 	__acornscsi_in(host->base + (offset << 1), ptr, this_len);
934 
935 	offset += this_len;
936 	ptr += this_len;
937 	len -= this_len;
938 
939 	if (offset == (1 << 12)) {
940 	    offset = 0;
941 	    page ++;
942 	    writeb((page & 0x3f) | host->card.page_reg, host->fast + PAGE_REG);
943 	}
944     }
945     writeb(host->card.page_reg, host->fast + PAGE_REG);
946 }
947 
948 /*
949  * Prototype: void acornscsi_data_write(AS_Host *host, char *ptr,
950  *				unsigned int start_addr, unsigned int length)
951  * Purpose  : write data to DMA RAM
952  * Params   : host - host to transfer from
953  *	      ptr  - DRAM address
954  *	      start_addr - host mem address
955  *	      length - number of bytes to transfer
956  * Notes    : this will only be one SG entry or less
957  */
958 static
959 void acornscsi_data_write(AS_Host *host, char *ptr,
960 				 unsigned int start_addr, unsigned int length)
961 {
962     extern void __acornscsi_out(void __iomem *, char *buf, int len);
963     unsigned int page, offset, len = length;
964 
965     page = (start_addr >> 12);
966     offset = start_addr & ((1 << 12) - 1);
967 
968     writeb((page & 0x3f) | host->card.page_reg, host->fast + PAGE_REG);
969 
970     while (len > 0) {
971 	unsigned int this_len;
972 
973 	if (len + offset > (1 << 12))
974 	    this_len = (1 << 12) - offset;
975 	else
976 	    this_len = len;
977 
978 	__acornscsi_out(host->base + (offset << 1), ptr, this_len);
979 
980 	offset += this_len;
981 	ptr += this_len;
982 	len -= this_len;
983 
984 	if (offset == (1 << 12)) {
985 	    offset = 0;
986 	    page ++;
987 	    writeb((page & 0x3f) | host->card.page_reg, host->fast + PAGE_REG);
988 	}
989     }
990     writeb(host->card.page_reg, host->fast + PAGE_REG);
991 }
992 
993 /* =========================================================================================
994  * On-board DMA routines
995  */
996 #ifdef USE_DMAC
997 /*
998  * Prototype: void acornscsi_dmastop(AS_Host *host)
999  * Purpose  : stop all DMA
1000  * Params   : host - host on which to stop DMA
1001  * Notes    : This is called when leaving DATA IN/OUT phase,
1002  *	      or when interface is RESET
1003  */
1004 static inline
1005 void acornscsi_dma_stop(AS_Host *host)
1006 {
1007     dmac_write(host, DMAC_MASKREG, MASK_ON);
1008     dmac_clearintr(host);
1009 
1010 #if (DEBUG & DEBUG_DMA)
1011     DBG(host->SCpnt, acornscsi_dumpdma(host, "stop"));
1012 #endif
1013 }
1014 
1015 /*
1016  * Function: void acornscsi_dma_setup(AS_Host *host, dmadir_t direction)
1017  * Purpose : setup DMA controller for data transfer
1018  * Params  : host - host to setup
1019  *	     direction - data transfer direction
1020  * Notes   : This is called when entering DATA I/O phase, not
1021  *	     while we're in a DATA I/O phase
1022  */
1023 static
1024 void acornscsi_dma_setup(AS_Host *host, dmadir_t direction)
1025 {
1026     unsigned int address, length, mode;
1027 
1028     host->dma.direction = direction;
1029 
1030     dmac_write(host, DMAC_MASKREG, MASK_ON);
1031 
1032     if (direction == DMA_OUT) {
1033 #if (DEBUG & DEBUG_NO_WRITE)
1034 	if (NO_WRITE & (1 << host->SCpnt->device->id)) {
1035 	    printk(KERN_CRIT "scsi%d.%c: I can't handle DMA_OUT!\n",
1036 		    host->host->host_no, acornscsi_target(host));
1037 	    return;
1038 	}
1039 #endif
1040 	mode = DMAC_WRITE;
1041     } else
1042 	mode = DMAC_READ;
1043 
1044     /*
1045      * Allocate some buffer space, limited to half the buffer size
1046      */
1047     length = min_t(unsigned int, host->scsi.SCp.this_residual, DMAC_BUFFER_SIZE / 2);
1048     if (length) {
1049 	host->dma.start_addr = address = host->dma.free_addr;
1050 	host->dma.free_addr = (host->dma.free_addr + length) &
1051 				(DMAC_BUFFER_SIZE - 1);
1052 
1053 	/*
1054 	 * Transfer data to DMA memory
1055 	 */
1056 	if (direction == DMA_OUT)
1057 	    acornscsi_data_write(host, host->scsi.SCp.ptr, host->dma.start_addr,
1058 				length);
1059 
1060 	length -= 1;
1061 	dmac_write(host, DMAC_TXCNTLO, length);
1062 	dmac_write(host, DMAC_TXCNTHI, length >> 8);
1063 	dmac_write(host, DMAC_TXADRLO, address);
1064 	dmac_write(host, DMAC_TXADRMD, address >> 8);
1065 	dmac_write(host, DMAC_TXADRHI, 0);
1066 	dmac_write(host, DMAC_MODECON, mode);
1067 	dmac_write(host, DMAC_MASKREG, MASK_OFF);
1068 
1069 #if (DEBUG & DEBUG_DMA)
1070 	DBG(host->SCpnt, acornscsi_dumpdma(host, "strt"));
1071 #endif
1072 	host->dma.xfer_setup = 1;
1073     }
1074 }
1075 
1076 /*
1077  * Function: void acornscsi_dma_cleanup(AS_Host *host)
1078  * Purpose : ensure that all DMA transfers are up-to-date & host->scsi.SCp is correct
1079  * Params  : host - host to finish
1080  * Notes   : This is called when a command is:
1081  *		terminating, RESTORE_POINTERS, SAVE_POINTERS, DISCONECT
1082  *	   : This must not return until all transfers are completed.
1083  */
1084 static
1085 void acornscsi_dma_cleanup(AS_Host *host)
1086 {
1087     dmac_write(host, DMAC_MASKREG, MASK_ON);
1088     dmac_clearintr(host);
1089 
1090     /*
1091      * Check for a pending transfer
1092      */
1093     if (host->dma.xfer_required) {
1094 	host->dma.xfer_required = 0;
1095 	if (host->dma.direction == DMA_IN)
1096 	    acornscsi_data_read(host, host->dma.xfer_ptr,
1097 				 host->dma.xfer_start, host->dma.xfer_length);
1098     }
1099 
1100     /*
1101      * Has a transfer been setup?
1102      */
1103     if (host->dma.xfer_setup) {
1104 	unsigned int transferred;
1105 
1106 	host->dma.xfer_setup = 0;
1107 
1108 #if (DEBUG & DEBUG_DMA)
1109 	DBG(host->SCpnt, acornscsi_dumpdma(host, "cupi"));
1110 #endif
1111 
1112 	/*
1113 	 * Calculate number of bytes transferred from DMA.
1114 	 */
1115 	transferred = dmac_address(host) - host->dma.start_addr;
1116 	host->dma.transferred += transferred;
1117 
1118 	if (host->dma.direction == DMA_IN)
1119 	    acornscsi_data_read(host, host->scsi.SCp.ptr,
1120 				 host->dma.start_addr, transferred);
1121 
1122 	/*
1123 	 * Update SCSI pointers
1124 	 */
1125 	acornscsi_data_updateptr(host, &host->scsi.SCp, transferred);
1126 #if (DEBUG & DEBUG_DMA)
1127 	DBG(host->SCpnt, acornscsi_dumpdma(host, "cupo"));
1128 #endif
1129     }
1130 }
1131 
1132 /*
1133  * Function: void acornscsi_dmacintr(AS_Host *host)
1134  * Purpose : handle interrupts from DMAC device
1135  * Params  : host - host to process
1136  * Notes   : If reading, we schedule the read to main memory &
1137  *	     allow the transfer to continue.
1138  *	   : If writing, we fill the onboard DMA memory from main
1139  *	     memory.
1140  *	   : Called whenever DMAC finished it's current transfer.
1141  */
1142 static
1143 void acornscsi_dma_intr(AS_Host *host)
1144 {
1145     unsigned int address, length, transferred;
1146 
1147 #if (DEBUG & DEBUG_DMA)
1148     DBG(host->SCpnt, acornscsi_dumpdma(host, "inti"));
1149 #endif
1150 
1151     dmac_write(host, DMAC_MASKREG, MASK_ON);
1152     dmac_clearintr(host);
1153 
1154     /*
1155      * Calculate amount transferred via DMA
1156      */
1157     transferred = dmac_address(host) - host->dma.start_addr;
1158     host->dma.transferred += transferred;
1159 
1160     /*
1161      * Schedule DMA transfer off board
1162      */
1163     if (host->dma.direction == DMA_IN) {
1164 	host->dma.xfer_start = host->dma.start_addr;
1165 	host->dma.xfer_length = transferred;
1166 	host->dma.xfer_ptr = host->scsi.SCp.ptr;
1167 	host->dma.xfer_required = 1;
1168     }
1169 
1170     acornscsi_data_updateptr(host, &host->scsi.SCp, transferred);
1171 
1172     /*
1173      * Allocate some buffer space, limited to half the on-board RAM size
1174      */
1175     length = min_t(unsigned int, host->scsi.SCp.this_residual, DMAC_BUFFER_SIZE / 2);
1176     if (length) {
1177 	host->dma.start_addr = address = host->dma.free_addr;
1178 	host->dma.free_addr = (host->dma.free_addr + length) &
1179 				(DMAC_BUFFER_SIZE - 1);
1180 
1181 	/*
1182 	 * Transfer data to DMA memory
1183 	 */
1184 	if (host->dma.direction == DMA_OUT)
1185 	    acornscsi_data_write(host, host->scsi.SCp.ptr, host->dma.start_addr,
1186 				length);
1187 
1188 	length -= 1;
1189 	dmac_write(host, DMAC_TXCNTLO, length);
1190 	dmac_write(host, DMAC_TXCNTHI, length >> 8);
1191 	dmac_write(host, DMAC_TXADRLO, address);
1192 	dmac_write(host, DMAC_TXADRMD, address >> 8);
1193 	dmac_write(host, DMAC_TXADRHI, 0);
1194 	dmac_write(host, DMAC_MASKREG, MASK_OFF);
1195 
1196 #if (DEBUG & DEBUG_DMA)
1197 	DBG(host->SCpnt, acornscsi_dumpdma(host, "into"));
1198 #endif
1199     } else {
1200 	host->dma.xfer_setup = 0;
1201 #if 0
1202 	/*
1203 	 * If the interface still wants more, then this is an error.
1204 	 * We give it another byte, but we also attempt to raise an
1205 	 * attention condition.  We continue giving one byte until
1206 	 * the device recognises the attention.
1207 	 */
1208 	if (dmac_read(host, DMAC_STATUS) & STATUS_RQ0) {
1209 	    acornscsi_abortcmd(host, host->SCpnt->tag);
1210 
1211 	    dmac_write(host, DMAC_TXCNTLO, 0);
1212 	    dmac_write(host, DMAC_TXCNTHI, 0);
1213 	    dmac_write(host, DMAC_TXADRLO, 0);
1214 	    dmac_write(host, DMAC_TXADRMD, 0);
1215 	    dmac_write(host, DMAC_TXADRHI, 0);
1216 	    dmac_write(host, DMAC_MASKREG, MASK_OFF);
1217 	}
1218 #endif
1219     }
1220 }
1221 
1222 /*
1223  * Function: void acornscsi_dma_xfer(AS_Host *host)
1224  * Purpose : transfer data between AcornSCSI and memory
1225  * Params  : host - host to process
1226  */
1227 static
1228 void acornscsi_dma_xfer(AS_Host *host)
1229 {
1230     host->dma.xfer_required = 0;
1231 
1232     if (host->dma.direction == DMA_IN)
1233 	acornscsi_data_read(host, host->dma.xfer_ptr,
1234 				host->dma.xfer_start, host->dma.xfer_length);
1235 }
1236 
1237 /*
1238  * Function: void acornscsi_dma_adjust(AS_Host *host)
1239  * Purpose : adjust DMA pointers & count for bytes transferred to
1240  *	     SBIC but not SCSI bus.
1241  * Params  : host - host to adjust DMA count for
1242  */
1243 static
1244 void acornscsi_dma_adjust(AS_Host *host)
1245 {
1246     if (host->dma.xfer_setup) {
1247 	signed long transferred;
1248 #if (DEBUG & (DEBUG_DMA|DEBUG_WRITE))
1249 	DBG(host->SCpnt, acornscsi_dumpdma(host, "adji"));
1250 #endif
1251 	/*
1252 	 * Calculate correct DMA address - DMA is ahead of SCSI bus while
1253 	 * writing.
1254 	 *  host->scsi.SCp.scsi_xferred is the number of bytes
1255 	 *  actually transferred to/from the SCSI bus.
1256 	 *  host->dma.transferred is the number of bytes transferred
1257 	 *  over DMA since host->dma.start_addr was last set.
1258 	 *
1259 	 * real_dma_addr = host->dma.start_addr + host->scsi.SCp.scsi_xferred
1260 	 *		   - host->dma.transferred
1261 	 */
1262 	transferred = host->scsi.SCp.scsi_xferred - host->dma.transferred;
1263 	if (transferred < 0)
1264 	    printk("scsi%d.%c: Ack! DMA write correction %ld < 0!\n",
1265 		    host->host->host_no, acornscsi_target(host), transferred);
1266 	else if (transferred == 0)
1267 	    host->dma.xfer_setup = 0;
1268 	else {
1269 	    transferred += host->dma.start_addr;
1270 	    dmac_write(host, DMAC_TXADRLO, transferred);
1271 	    dmac_write(host, DMAC_TXADRMD, transferred >> 8);
1272 	    dmac_write(host, DMAC_TXADRHI, transferred >> 16);
1273 #if (DEBUG & (DEBUG_DMA|DEBUG_WRITE))
1274 	    DBG(host->SCpnt, acornscsi_dumpdma(host, "adjo"));
1275 #endif
1276 	}
1277     }
1278 }
1279 #endif
1280 
1281 /* =========================================================================================
1282  * Data I/O
1283  */
1284 static int
1285 acornscsi_write_pio(AS_Host *host, char *bytes, int *ptr, int len, unsigned int max_timeout)
1286 {
1287 	unsigned int asr, timeout = max_timeout;
1288 	int my_ptr = *ptr;
1289 
1290 	while (my_ptr < len) {
1291 		asr = sbic_arm_read(host, SBIC_ASR);
1292 
1293 		if (asr & ASR_DBR) {
1294 			timeout = max_timeout;
1295 
1296 			sbic_arm_write(host, SBIC_DATA, bytes[my_ptr++]);
1297 		} else if (asr & ASR_INT)
1298 			break;
1299 		else if (--timeout == 0)
1300 			break;
1301 		udelay(1);
1302 	}
1303 
1304 	*ptr = my_ptr;
1305 
1306 	return (timeout == 0) ? -1 : 0;
1307 }
1308 
1309 /*
1310  * Function: void acornscsi_sendcommand(AS_Host *host)
1311  * Purpose : send a command to a target
1312  * Params  : host - host which is connected to target
1313  */
1314 static void
1315 acornscsi_sendcommand(AS_Host *host)
1316 {
1317 	struct scsi_cmnd *SCpnt = host->SCpnt;
1318 
1319     sbic_arm_write(host, SBIC_TRANSCNTH, 0);
1320     sbic_arm_writenext(host, 0);
1321     sbic_arm_writenext(host, SCpnt->cmd_len - host->scsi.SCp.sent_command);
1322 
1323     acornscsi_sbic_issuecmd(host, CMND_XFERINFO);
1324 
1325     if (acornscsi_write_pio(host, SCpnt->cmnd,
1326 	(int *)&host->scsi.SCp.sent_command, SCpnt->cmd_len, 1000000))
1327 	printk("scsi%d: timeout while sending command\n", host->host->host_no);
1328 
1329     host->scsi.phase = PHASE_COMMAND;
1330 }
1331 
1332 static
1333 void acornscsi_sendmessage(AS_Host *host)
1334 {
1335     unsigned int message_length = msgqueue_msglength(&host->scsi.msgs);
1336     unsigned int msgnr;
1337     struct message *msg;
1338 
1339 #if (DEBUG & DEBUG_MESSAGES)
1340     printk("scsi%d.%c: sending message ",
1341 	    host->host->host_no, acornscsi_target(host));
1342 #endif
1343 
1344     switch (message_length) {
1345     case 0:
1346 	acornscsi_sbic_issuecmd(host, CMND_XFERINFO | CMND_SBT);
1347 
1348 	acornscsi_sbic_wait(host, ASR_DBR, ASR_DBR, 1000, "sending message 1");
1349 
1350 	sbic_arm_write(host, SBIC_DATA, NOP);
1351 
1352 	host->scsi.last_message = NOP;
1353 #if (DEBUG & DEBUG_MESSAGES)
1354 	printk("NOP");
1355 #endif
1356 	break;
1357 
1358     case 1:
1359 	acornscsi_sbic_issuecmd(host, CMND_XFERINFO | CMND_SBT);
1360 	msg = msgqueue_getmsg(&host->scsi.msgs, 0);
1361 
1362 	acornscsi_sbic_wait(host, ASR_DBR, ASR_DBR, 1000, "sending message 2");
1363 
1364 	sbic_arm_write(host, SBIC_DATA, msg->msg[0]);
1365 
1366 	host->scsi.last_message = msg->msg[0];
1367 #if (DEBUG & DEBUG_MESSAGES)
1368 	spi_print_msg(msg->msg);
1369 #endif
1370 	break;
1371 
1372     default:
1373 	/*
1374 	 * ANSI standard says: (SCSI-2 Rev 10c Sect 5.6.14)
1375 	 * 'When a target sends this (MESSAGE_REJECT) message, it
1376 	 *  shall change to MESSAGE IN phase and send this message
1377 	 *  prior to requesting additional message bytes from the
1378 	 *  initiator.  This provides an interlock so that the
1379 	 *  initiator can determine which message byte is rejected.
1380 	 */
1381 	sbic_arm_write(host, SBIC_TRANSCNTH, 0);
1382 	sbic_arm_writenext(host, 0);
1383 	sbic_arm_writenext(host, message_length);
1384 	acornscsi_sbic_issuecmd(host, CMND_XFERINFO);
1385 
1386 	msgnr = 0;
1387 	while ((msg = msgqueue_getmsg(&host->scsi.msgs, msgnr++)) != NULL) {
1388 	    unsigned int i;
1389 #if (DEBUG & DEBUG_MESSAGES)
1390 	    spi_print_msg(msg);
1391 #endif
1392 	    i = 0;
1393 	    if (acornscsi_write_pio(host, msg->msg, &i, msg->length, 1000000))
1394 		printk("scsi%d: timeout while sending message\n", host->host->host_no);
1395 
1396 	    host->scsi.last_message = msg->msg[0];
1397 	    if (msg->msg[0] == EXTENDED_MESSAGE)
1398 		host->scsi.last_message |= msg->msg[2] << 8;
1399 
1400 	    if (i != msg->length)
1401 		break;
1402 	}
1403 	break;
1404     }
1405 #if (DEBUG & DEBUG_MESSAGES)
1406     printk("\n");
1407 #endif
1408 }
1409 
1410 /*
1411  * Function: void acornscsi_readstatusbyte(AS_Host *host)
1412  * Purpose : Read status byte from connected target
1413  * Params  : host - host connected to target
1414  */
1415 static
1416 void acornscsi_readstatusbyte(AS_Host *host)
1417 {
1418     acornscsi_sbic_issuecmd(host, CMND_XFERINFO|CMND_SBT);
1419     acornscsi_sbic_wait(host, ASR_DBR, ASR_DBR, 1000, "reading status byte");
1420     host->scsi.SCp.Status = sbic_arm_read(host, SBIC_DATA);
1421 }
1422 
1423 /*
1424  * Function: unsigned char acornscsi_readmessagebyte(AS_Host *host)
1425  * Purpose : Read one message byte from connected target
1426  * Params  : host - host connected to target
1427  */
1428 static
1429 unsigned char acornscsi_readmessagebyte(AS_Host *host)
1430 {
1431     unsigned char message;
1432 
1433     acornscsi_sbic_issuecmd(host, CMND_XFERINFO | CMND_SBT);
1434 
1435     acornscsi_sbic_wait(host, ASR_DBR, ASR_DBR, 1000, "for message byte");
1436 
1437     message = sbic_arm_read(host, SBIC_DATA);
1438 
1439     /* wait for MSGIN-XFER-PAUSED */
1440     acornscsi_sbic_wait(host, ASR_INT, ASR_INT, 1000, "for interrupt after message byte");
1441 
1442     sbic_arm_read(host, SBIC_SSR);
1443 
1444     return message;
1445 }
1446 
1447 /*
1448  * Function: void acornscsi_message(AS_Host *host)
1449  * Purpose : Read complete message from connected target & action message
1450  * Params  : host - host connected to target
1451  */
1452 static
1453 void acornscsi_message(AS_Host *host)
1454 {
1455     unsigned char message[16];
1456     unsigned int msgidx = 0, msglen = 1;
1457 
1458     do {
1459 	message[msgidx] = acornscsi_readmessagebyte(host);
1460 
1461 	switch (msgidx) {
1462 	case 0:
1463 	    if (message[0] == EXTENDED_MESSAGE ||
1464 		(message[0] >= 0x20 && message[0] <= 0x2f))
1465 		msglen = 2;
1466 	    break;
1467 
1468 	case 1:
1469 	    if (message[0] == EXTENDED_MESSAGE)
1470 		msglen += message[msgidx];
1471 	    break;
1472 	}
1473 	msgidx += 1;
1474 	if (msgidx < msglen) {
1475 	    acornscsi_sbic_issuecmd(host, CMND_NEGATEACK);
1476 
1477 	    /* wait for next msg-in */
1478 	    acornscsi_sbic_wait(host, ASR_INT, ASR_INT, 1000, "for interrupt after negate ack");
1479 	    sbic_arm_read(host, SBIC_SSR);
1480 	}
1481     } while (msgidx < msglen);
1482 
1483 #if (DEBUG & DEBUG_MESSAGES)
1484     printk("scsi%d.%c: message in: ",
1485 	    host->host->host_no, acornscsi_target(host));
1486     spi_print_msg(message);
1487     printk("\n");
1488 #endif
1489 
1490     if (host->scsi.phase == PHASE_RECONNECTED) {
1491 	/*
1492 	 * ANSI standard says: (Section SCSI-2 Rev. 10c Sect 5.6.17)
1493 	 * 'Whenever a target reconnects to an initiator to continue
1494 	 *  a tagged I/O process, the SIMPLE QUEUE TAG message shall
1495 	 *  be sent immediately following the IDENTIFY message...'
1496 	 */
1497 	if (message[0] == SIMPLE_QUEUE_TAG)
1498 	    host->scsi.reconnected.tag = message[1];
1499 	if (acornscsi_reconnect_finish(host))
1500 	    host->scsi.phase = PHASE_MSGIN;
1501     }
1502 
1503     switch (message[0]) {
1504     case ABORT:
1505     case ABORT_TAG:
1506     case COMMAND_COMPLETE:
1507 	if (host->scsi.phase != PHASE_STATUSIN) {
1508 	    printk(KERN_ERR "scsi%d.%c: command complete following non-status in phase?\n",
1509 		    host->host->host_no, acornscsi_target(host));
1510 	    acornscsi_dumplog(host, host->SCpnt->device->id);
1511 	}
1512 	host->scsi.phase = PHASE_DONE;
1513 	host->scsi.SCp.Message = message[0];
1514 	break;
1515 
1516     case SAVE_POINTERS:
1517 	/*
1518 	 * ANSI standard says: (Section SCSI-2 Rev. 10c Sect 5.6.20)
1519 	 * 'The SAVE DATA POINTER message is sent from a target to
1520 	 *  direct the initiator to copy the active data pointer to
1521 	 *  the saved data pointer for the current I/O process.
1522 	 */
1523 	acornscsi_dma_cleanup(host);
1524 	host->SCpnt->SCp = host->scsi.SCp;
1525 	host->SCpnt->SCp.sent_command = 0;
1526 	host->scsi.phase = PHASE_MSGIN;
1527 	break;
1528 
1529     case RESTORE_POINTERS:
1530 	/*
1531 	 * ANSI standard says: (Section SCSI-2 Rev. 10c Sect 5.6.19)
1532 	 * 'The RESTORE POINTERS message is sent from a target to
1533 	 *  direct the initiator to copy the most recently saved
1534 	 *  command, data, and status pointers for the I/O process
1535 	 *  to the corresponding active pointers.  The command and
1536 	 *  status pointers shall be restored to the beginning of
1537 	 *  the present command and status areas.'
1538 	 */
1539 	acornscsi_dma_cleanup(host);
1540 	host->scsi.SCp = host->SCpnt->SCp;
1541 	host->scsi.phase = PHASE_MSGIN;
1542 	break;
1543 
1544     case DISCONNECT:
1545 	/*
1546 	 * ANSI standard says: (Section SCSI-2 Rev. 10c Sect 6.4.2)
1547 	 * 'On those occasions when an error or exception condition occurs
1548 	 *  and the target elects to repeat the information transfer, the
1549 	 *  target may repeat the transfer either issuing a RESTORE POINTERS
1550 	 *  message or by disconnecting without issuing a SAVE POINTERS
1551 	 *  message.  When reconnection is completed, the most recent
1552 	 *  saved pointer values are restored.'
1553 	 */
1554 	acornscsi_dma_cleanup(host);
1555 	host->scsi.phase = PHASE_DISCONNECT;
1556 	break;
1557 
1558     case MESSAGE_REJECT:
1559 #if 0 /* this isn't needed any more */
1560 	/*
1561 	 * If we were negociating sync transfer, we don't yet know if
1562 	 * this REJECT is for the sync transfer or for the tagged queue/wide
1563 	 * transfer.  Re-initiate sync transfer negotiation now, and if
1564 	 * we got a REJECT in response to SDTR, then it'll be set to DONE.
1565 	 */
1566 	if (host->device[host->SCpnt->device->id].sync_state == SYNC_SENT_REQUEST)
1567 	    host->device[host->SCpnt->device->id].sync_state = SYNC_NEGOCIATE;
1568 #endif
1569 
1570 	/*
1571 	 * If we have any messages waiting to go out, then assert ATN now
1572 	 */
1573 	if (msgqueue_msglength(&host->scsi.msgs))
1574 	    acornscsi_sbic_issuecmd(host, CMND_ASSERTATN);
1575 
1576 	switch (host->scsi.last_message) {
1577 #ifdef CONFIG_SCSI_ACORNSCSI_TAGGED_QUEUE
1578 	case HEAD_OF_QUEUE_TAG:
1579 	case ORDERED_QUEUE_TAG:
1580 	case SIMPLE_QUEUE_TAG:
1581 	    /*
1582 	     * ANSI standard says: (Section SCSI-2 Rev. 10c Sect 5.6.17)
1583 	     *  If a target does not implement tagged queuing and a queue tag
1584 	     *  message is received, it shall respond with a MESSAGE REJECT
1585 	     *  message and accept the I/O process as if it were untagged.
1586 	     */
1587 	    printk(KERN_NOTICE "scsi%d.%c: disabling tagged queueing\n",
1588 		    host->host->host_no, acornscsi_target(host));
1589 	    host->SCpnt->device->simple_tags = 0;
1590 	    set_bit(host->SCpnt->device->id * 8 + host->SCpnt->device->lun, host->busyluns);
1591 	    break;
1592 #endif
1593 	case EXTENDED_MESSAGE | (EXTENDED_SDTR << 8):
1594 	    /*
1595 	     * Target can't handle synchronous transfers
1596 	     */
1597 	    printk(KERN_NOTICE "scsi%d.%c: Using asynchronous transfer\n",
1598 		    host->host->host_no, acornscsi_target(host));
1599 	    host->device[host->SCpnt->device->id].sync_xfer = SYNCHTRANSFER_2DBA;
1600 	    host->device[host->SCpnt->device->id].sync_state = SYNC_ASYNCHRONOUS;
1601 	    sbic_arm_write(host, SBIC_SYNCHTRANSFER, host->device[host->SCpnt->device->id].sync_xfer);
1602 	    break;
1603 
1604 	default:
1605 	    break;
1606 	}
1607 	break;
1608 
1609     case QUEUE_FULL:
1610 	/* TODO: target queue is full */
1611 	break;
1612 
1613     case SIMPLE_QUEUE_TAG:
1614 	/* tag queue reconnect... message[1] = queue tag.  Print something to indicate something happened! */
1615 	printk("scsi%d.%c: reconnect queue tag %02X\n",
1616 		host->host->host_no, acornscsi_target(host),
1617 		message[1]);
1618 	break;
1619 
1620     case EXTENDED_MESSAGE:
1621 	switch (message[2]) {
1622 #ifdef CONFIG_SCSI_ACORNSCSI_SYNC
1623 	case EXTENDED_SDTR:
1624 	    if (host->device[host->SCpnt->device->id].sync_state == SYNC_SENT_REQUEST) {
1625 		/*
1626 		 * We requested synchronous transfers.  This isn't quite right...
1627 		 * We can only say if this succeeded if we proceed on to execute the
1628 		 * command from this message.  If we get a MESSAGE PARITY ERROR,
1629 		 * and the target retries fail, then we fallback to asynchronous mode
1630 		 */
1631 		host->device[host->SCpnt->device->id].sync_state = SYNC_COMPLETED;
1632 		printk(KERN_NOTICE "scsi%d.%c: Using synchronous transfer, offset %d, %d ns\n",
1633 			host->host->host_no, acornscsi_target(host),
1634 			message[4], message[3] * 4);
1635 		host->device[host->SCpnt->device->id].sync_xfer =
1636 			calc_sync_xfer(message[3] * 4, message[4]);
1637 	    } else {
1638 		unsigned char period, length;
1639 		/*
1640 		 * Target requested synchronous transfers.  The agreement is only
1641 		 * to be in operation AFTER the target leaves message out phase.
1642 		 */
1643 		acornscsi_sbic_issuecmd(host, CMND_ASSERTATN);
1644 		period = max_t(unsigned int, message[3], sdtr_period / 4);
1645 		length = min_t(unsigned int, message[4], sdtr_size);
1646 		msgqueue_addmsg(&host->scsi.msgs, 5, EXTENDED_MESSAGE, 3,
1647 				 EXTENDED_SDTR, period, length);
1648 		host->device[host->SCpnt->device->id].sync_xfer =
1649 			calc_sync_xfer(period * 4, length);
1650 	    }
1651 	    sbic_arm_write(host, SBIC_SYNCHTRANSFER, host->device[host->SCpnt->device->id].sync_xfer);
1652 	    break;
1653 #else
1654 	    /* We do not accept synchronous transfers.  Respond with a
1655 	     * MESSAGE_REJECT.
1656 	     */
1657 #endif
1658 
1659 	case EXTENDED_WDTR:
1660 	    /* The WD33C93A is only 8-bit.  We respond with a MESSAGE_REJECT
1661 	     * to a wide data transfer request.
1662 	     */
1663 	default:
1664 	    acornscsi_sbic_issuecmd(host, CMND_ASSERTATN);
1665 	    msgqueue_flush(&host->scsi.msgs);
1666 	    msgqueue_addmsg(&host->scsi.msgs, 1, MESSAGE_REJECT);
1667 	    break;
1668 	}
1669 	break;
1670 
1671 #ifdef CONFIG_SCSI_ACORNSCSI_LINK
1672     case LINKED_CMD_COMPLETE:
1673     case LINKED_FLG_CMD_COMPLETE:
1674 	/*
1675 	 * We don't support linked commands yet
1676 	 */
1677 	if (0) {
1678 #if (DEBUG & DEBUG_LINK)
1679 	    printk("scsi%d.%c: lun %d tag %d linked command complete\n",
1680 		    host->host->host_no, acornscsi_target(host), host->SCpnt->tag);
1681 #endif
1682 	    /*
1683 	     * A linked command should only terminate with one of these messages
1684 	     * if there are more linked commands available.
1685 	     */
1686 	    if (!host->SCpnt->next_link) {
1687 		printk(KERN_WARNING "scsi%d.%c: lun %d tag %d linked command complete, but no next_link\n",
1688 			instance->host_no, acornscsi_target(host), host->SCpnt->tag);
1689 		acornscsi_sbic_issuecmd(host, CMND_ASSERTATN);
1690 		msgqueue_addmsg(&host->scsi.msgs, 1, ABORT);
1691 	    } else {
1692 		struct scsi_cmnd *SCpnt = host->SCpnt;
1693 
1694 		acornscsi_dma_cleanup(host);
1695 
1696 		host->SCpnt = host->SCpnt->next_link;
1697 		host->SCpnt->tag = SCpnt->tag;
1698 		SCpnt->result = DID_OK | host->scsi.SCp.Message << 8 | host->Scsi.SCp.Status;
1699 		SCpnt->done(SCpnt);
1700 
1701 		/* initialise host->SCpnt->SCp */
1702 	    }
1703 	    break;
1704 	}
1705 #endif
1706 
1707     default: /* reject message */
1708 	printk(KERN_ERR "scsi%d.%c: unrecognised message %02X, rejecting\n",
1709 		host->host->host_no, acornscsi_target(host),
1710 		message[0]);
1711 	acornscsi_sbic_issuecmd(host, CMND_ASSERTATN);
1712 	msgqueue_flush(&host->scsi.msgs);
1713 	msgqueue_addmsg(&host->scsi.msgs, 1, MESSAGE_REJECT);
1714 	host->scsi.phase = PHASE_MSGIN;
1715 	break;
1716     }
1717     acornscsi_sbic_issuecmd(host, CMND_NEGATEACK);
1718 }
1719 
1720 /*
1721  * Function: int acornscsi_buildmessages(AS_Host *host)
1722  * Purpose : build the connection messages for a host
1723  * Params  : host - host to add messages to
1724  */
1725 static
1726 void acornscsi_buildmessages(AS_Host *host)
1727 {
1728 #if 0
1729     /* does the device need resetting? */
1730     if (cmd_reset) {
1731 	msgqueue_addmsg(&host->scsi.msgs, 1, BUS_DEVICE_RESET);
1732 	return;
1733     }
1734 #endif
1735 
1736     msgqueue_addmsg(&host->scsi.msgs, 1,
1737 		     IDENTIFY(host->device[host->SCpnt->device->id].disconnect_ok,
1738 			     host->SCpnt->device->lun));
1739 
1740 #if 0
1741     /* does the device need the current command aborted */
1742     if (cmd_aborted) {
1743 	acornscsi_abortcmd(host->SCpnt->tag);
1744 	return;
1745     }
1746 #endif
1747 
1748 #ifdef CONFIG_SCSI_ACORNSCSI_TAGGED_QUEUE
1749     if (host->SCpnt->tag) {
1750 	unsigned int tag_type;
1751 
1752 	if (host->SCpnt->cmnd[0] == REQUEST_SENSE ||
1753 	    host->SCpnt->cmnd[0] == TEST_UNIT_READY ||
1754 	    host->SCpnt->cmnd[0] == INQUIRY)
1755 	    tag_type = HEAD_OF_QUEUE_TAG;
1756 	else
1757 	    tag_type = SIMPLE_QUEUE_TAG;
1758 	msgqueue_addmsg(&host->scsi.msgs, 2, tag_type, host->SCpnt->tag);
1759     }
1760 #endif
1761 
1762 #ifdef CONFIG_SCSI_ACORNSCSI_SYNC
1763     if (host->device[host->SCpnt->device->id].sync_state == SYNC_NEGOCIATE) {
1764 	host->device[host->SCpnt->device->id].sync_state = SYNC_SENT_REQUEST;
1765 	msgqueue_addmsg(&host->scsi.msgs, 5,
1766 			 EXTENDED_MESSAGE, 3, EXTENDED_SDTR,
1767 			 sdtr_period / 4, sdtr_size);
1768     }
1769 #endif
1770 }
1771 
1772 /*
1773  * Function: int acornscsi_starttransfer(AS_Host *host)
1774  * Purpose : transfer data to/from connected target
1775  * Params  : host - host to which target is connected
1776  * Returns : 0 if failure
1777  */
1778 static
1779 int acornscsi_starttransfer(AS_Host *host)
1780 {
1781     int residual;
1782 
1783     if (!host->scsi.SCp.ptr /*&& host->scsi.SCp.this_residual*/) {
1784 	printk(KERN_ERR "scsi%d.%c: null buffer passed to acornscsi_starttransfer\n",
1785 		host->host->host_no, acornscsi_target(host));
1786 	return 0;
1787     }
1788 
1789     residual = scsi_bufflen(host->SCpnt) - host->scsi.SCp.scsi_xferred;
1790 
1791     sbic_arm_write(host, SBIC_SYNCHTRANSFER, host->device[host->SCpnt->device->id].sync_xfer);
1792     sbic_arm_writenext(host, residual >> 16);
1793     sbic_arm_writenext(host, residual >> 8);
1794     sbic_arm_writenext(host, residual);
1795     acornscsi_sbic_issuecmd(host, CMND_XFERINFO);
1796     return 1;
1797 }
1798 
1799 /* =========================================================================================
1800  * Connection & Disconnection
1801  */
1802 /*
1803  * Function : acornscsi_reconnect(AS_Host *host)
1804  * Purpose  : reconnect a previously disconnected command
1805  * Params   : host - host specific data
1806  * Remarks  : SCSI spec says:
1807  *		'The set of active pointers is restored from the set
1808  *		 of saved pointers upon reconnection of the I/O process'
1809  */
1810 static
1811 int acornscsi_reconnect(AS_Host *host)
1812 {
1813     unsigned int target, lun, ok = 0;
1814 
1815     target = sbic_arm_read(host, SBIC_SOURCEID);
1816 
1817     if (!(target & 8))
1818 	printk(KERN_ERR "scsi%d: invalid source id after reselection "
1819 		"- device fault?\n",
1820 		host->host->host_no);
1821 
1822     target &= 7;
1823 
1824     if (host->SCpnt && !host->scsi.disconnectable) {
1825 	printk(KERN_ERR "scsi%d.%d: reconnected while command in "
1826 		"progress to target %d?\n",
1827 		host->host->host_no, target, host->SCpnt->device->id);
1828 	host->SCpnt = NULL;
1829     }
1830 
1831     lun = sbic_arm_read(host, SBIC_DATA) & 7;
1832 
1833     host->scsi.reconnected.target = target;
1834     host->scsi.reconnected.lun = lun;
1835     host->scsi.reconnected.tag = 0;
1836 
1837     if (host->scsi.disconnectable && host->SCpnt &&
1838 	host->SCpnt->device->id == target && host->SCpnt->device->lun == lun)
1839 	ok = 1;
1840 
1841     if (!ok && queue_probetgtlun(&host->queues.disconnected, target, lun))
1842 	ok = 1;
1843 
1844     ADD_STATUS(target, 0x81, host->scsi.phase, 0);
1845 
1846     if (ok) {
1847 	host->scsi.phase = PHASE_RECONNECTED;
1848     } else {
1849 	/* this doesn't seem to work */
1850 	printk(KERN_ERR "scsi%d.%c: reselected with no command "
1851 		"to reconnect with\n",
1852 		host->host->host_no, '0' + target);
1853 	acornscsi_dumplog(host, target);
1854 	acornscsi_abortcmd(host, 0);
1855 	if (host->SCpnt) {
1856 	    queue_add_cmd_tail(&host->queues.disconnected, host->SCpnt);
1857 	    host->SCpnt = NULL;
1858 	}
1859     }
1860     acornscsi_sbic_issuecmd(host, CMND_NEGATEACK);
1861     return !ok;
1862 }
1863 
1864 /*
1865  * Function: int acornscsi_reconect_finish(AS_Host *host)
1866  * Purpose : finish reconnecting a command
1867  * Params  : host - host to complete
1868  * Returns : 0 if failed
1869  */
1870 static
1871 int acornscsi_reconnect_finish(AS_Host *host)
1872 {
1873     if (host->scsi.disconnectable && host->SCpnt) {
1874 	host->scsi.disconnectable = 0;
1875 	if (host->SCpnt->device->id  == host->scsi.reconnected.target &&
1876 	    host->SCpnt->device->lun == host->scsi.reconnected.lun &&
1877 	    host->SCpnt->tag         == host->scsi.reconnected.tag) {
1878 #if (DEBUG & (DEBUG_QUEUES|DEBUG_DISCON))
1879 	    DBG(host->SCpnt, printk("scsi%d.%c: reconnected",
1880 		    host->host->host_no, acornscsi_target(host)));
1881 #endif
1882 	} else {
1883 	    queue_add_cmd_tail(&host->queues.disconnected, host->SCpnt);
1884 #if (DEBUG & (DEBUG_QUEUES|DEBUG_DISCON))
1885 	    DBG(host->SCpnt, printk("scsi%d.%c: had to move command "
1886 		    "to disconnected queue\n",
1887 		    host->host->host_no, acornscsi_target(host)));
1888 #endif
1889 	    host->SCpnt = NULL;
1890 	}
1891     }
1892     if (!host->SCpnt) {
1893 	host->SCpnt = queue_remove_tgtluntag(&host->queues.disconnected,
1894 				host->scsi.reconnected.target,
1895 				host->scsi.reconnected.lun,
1896 				host->scsi.reconnected.tag);
1897 #if (DEBUG & (DEBUG_QUEUES|DEBUG_DISCON))
1898 	DBG(host->SCpnt, printk("scsi%d.%c: had to get command",
1899 		host->host->host_no, acornscsi_target(host)));
1900 #endif
1901     }
1902 
1903     if (!host->SCpnt)
1904 	acornscsi_abortcmd(host, host->scsi.reconnected.tag);
1905     else {
1906 	/*
1907 	 * Restore data pointer from SAVED pointers.
1908 	 */
1909 	host->scsi.SCp = host->SCpnt->SCp;
1910 #if (DEBUG & (DEBUG_QUEUES|DEBUG_DISCON))
1911 	printk(", data pointers: [%p, %X]",
1912 		host->scsi.SCp.ptr, host->scsi.SCp.this_residual);
1913 #endif
1914     }
1915 #if (DEBUG & (DEBUG_QUEUES|DEBUG_DISCON))
1916     printk("\n");
1917 #endif
1918 
1919     host->dma.transferred = host->scsi.SCp.scsi_xferred;
1920 
1921     return host->SCpnt != NULL;
1922 }
1923 
1924 /*
1925  * Function: void acornscsi_disconnect_unexpected(AS_Host *host)
1926  * Purpose : handle an unexpected disconnect
1927  * Params  : host - host on which disconnect occurred
1928  */
1929 static
1930 void acornscsi_disconnect_unexpected(AS_Host *host)
1931 {
1932     printk(KERN_ERR "scsi%d.%c: unexpected disconnect\n",
1933 	    host->host->host_no, acornscsi_target(host));
1934 #if (DEBUG & DEBUG_ABORT)
1935     acornscsi_dumplog(host, 8);
1936 #endif
1937 
1938     acornscsi_done(host, &host->SCpnt, DID_ERROR);
1939 }
1940 
1941 /*
1942  * Function: void acornscsi_abortcmd(AS_host *host, unsigned char tag)
1943  * Purpose : abort a currently executing command
1944  * Params  : host - host with connected command to abort
1945  *	     tag  - tag to abort
1946  */
1947 static
1948 void acornscsi_abortcmd(AS_Host *host, unsigned char tag)
1949 {
1950     host->scsi.phase = PHASE_ABORTED;
1951     sbic_arm_write(host, SBIC_CMND, CMND_ASSERTATN);
1952 
1953     msgqueue_flush(&host->scsi.msgs);
1954 #ifdef CONFIG_SCSI_ACORNSCSI_TAGGED_QUEUE
1955     if (tag)
1956 	msgqueue_addmsg(&host->scsi.msgs, 2, ABORT_TAG, tag);
1957     else
1958 #endif
1959 	msgqueue_addmsg(&host->scsi.msgs, 1, ABORT);
1960 }
1961 
1962 /* ==========================================================================================
1963  * Interrupt routines.
1964  */
1965 /*
1966  * Function: int acornscsi_sbicintr(AS_Host *host)
1967  * Purpose : handle interrupts from SCSI device
1968  * Params  : host - host to process
1969  * Returns : INTR_PROCESS if expecting another SBIC interrupt
1970  *	     INTR_IDLE if no interrupt
1971  *	     INTR_NEXT_COMMAND if we have finished processing the command
1972  */
1973 static
1974 intr_ret_t acornscsi_sbicintr(AS_Host *host, int in_irq)
1975 {
1976     unsigned int asr, ssr;
1977 
1978     asr = sbic_arm_read(host, SBIC_ASR);
1979     if (!(asr & ASR_INT))
1980 	return INTR_IDLE;
1981 
1982     ssr = sbic_arm_read(host, SBIC_SSR);
1983 
1984 #if (DEBUG & DEBUG_PHASES)
1985     print_sbic_status(asr, ssr, host->scsi.phase);
1986 #endif
1987 
1988     ADD_STATUS(8, ssr, host->scsi.phase, in_irq);
1989 
1990     if (host->SCpnt && !host->scsi.disconnectable)
1991 	ADD_STATUS(host->SCpnt->device->id, ssr, host->scsi.phase, in_irq);
1992 
1993     switch (ssr) {
1994     case 0x00:				/* reset state - not advanced			*/
1995 	printk(KERN_ERR "scsi%d: reset in standard mode but wanted advanced mode.\n",
1996 		host->host->host_no);
1997 	/* setup sbic - WD33C93A */
1998 	sbic_arm_write(host, SBIC_OWNID, OWNID_EAF | host->host->this_id);
1999 	sbic_arm_write(host, SBIC_CMND, CMND_RESET);
2000 	return INTR_IDLE;
2001 
2002     case 0x01:				/* reset state - advanced			*/
2003 	sbic_arm_write(host, SBIC_CTRL, INIT_SBICDMA | CTRL_IDI);
2004 	sbic_arm_write(host, SBIC_TIMEOUT, TIMEOUT_TIME);
2005 	sbic_arm_write(host, SBIC_SYNCHTRANSFER, SYNCHTRANSFER_2DBA);
2006 	sbic_arm_write(host, SBIC_SOURCEID, SOURCEID_ER | SOURCEID_DSP);
2007 	msgqueue_flush(&host->scsi.msgs);
2008 	return INTR_IDLE;
2009 
2010     case 0x41:				/* unexpected disconnect aborted command	*/
2011 	acornscsi_disconnect_unexpected(host);
2012 	return INTR_NEXT_COMMAND;
2013     }
2014 
2015     switch (host->scsi.phase) {
2016     case PHASE_CONNECTING:		/* STATE: command removed from issue queue	*/
2017 	switch (ssr) {
2018 	case 0x11:			/* -> PHASE_CONNECTED				*/
2019 	    /* BUS FREE -> SELECTION */
2020 	    host->scsi.phase = PHASE_CONNECTED;
2021 	    msgqueue_flush(&host->scsi.msgs);
2022 	    host->dma.transferred = host->scsi.SCp.scsi_xferred;
2023 	    /* 33C93 gives next interrupt indicating bus phase */
2024 	    asr = sbic_arm_read(host, SBIC_ASR);
2025 	    if (!(asr & ASR_INT))
2026 		break;
2027 	    ssr = sbic_arm_read(host, SBIC_SSR);
2028 	    ADD_STATUS(8, ssr, host->scsi.phase, 1);
2029 	    ADD_STATUS(host->SCpnt->device->id, ssr, host->scsi.phase, 1);
2030 	    goto connected;
2031 
2032 	case 0x42:			/* select timed out				*/
2033 					/* -> PHASE_IDLE				*/
2034 	    acornscsi_done(host, &host->SCpnt, DID_NO_CONNECT);
2035 	    return INTR_NEXT_COMMAND;
2036 
2037 	case 0x81:			/* -> PHASE_RECONNECTED or PHASE_ABORTED	*/
2038 	    /* BUS FREE -> RESELECTION */
2039 	    host->origSCpnt = host->SCpnt;
2040 	    host->SCpnt = NULL;
2041 	    msgqueue_flush(&host->scsi.msgs);
2042 	    acornscsi_reconnect(host);
2043 	    break;
2044 
2045 	default:
2046 	    printk(KERN_ERR "scsi%d.%c: PHASE_CONNECTING, SSR %02X?\n",
2047 		    host->host->host_no, acornscsi_target(host), ssr);
2048 	    acornscsi_dumplog(host, host->SCpnt ? host->SCpnt->device->id : 8);
2049 	    acornscsi_abortcmd(host, host->SCpnt->tag);
2050 	}
2051 	return INTR_PROCESSING;
2052 
2053     connected:
2054     case PHASE_CONNECTED:		/* STATE: device selected ok			*/
2055 	switch (ssr) {
2056 #ifdef NONSTANDARD
2057 	case 0x8a:			/* -> PHASE_COMMAND, PHASE_COMMANDPAUSED	*/
2058 	    /* SELECTION -> COMMAND */
2059 	    acornscsi_sendcommand(host);
2060 	    break;
2061 
2062 	case 0x8b:			/* -> PHASE_STATUS				*/
2063 	    /* SELECTION -> STATUS */
2064 	    acornscsi_readstatusbyte(host);
2065 	    host->scsi.phase = PHASE_STATUSIN;
2066 	    break;
2067 #endif
2068 
2069 	case 0x8e:			/* -> PHASE_MSGOUT				*/
2070 	    /* SELECTION ->MESSAGE OUT */
2071 	    host->scsi.phase = PHASE_MSGOUT;
2072 	    acornscsi_buildmessages(host);
2073 	    acornscsi_sendmessage(host);
2074 	    break;
2075 
2076 	/* these should not happen */
2077 	case 0x85:			/* target disconnected				*/
2078 	    acornscsi_done(host, &host->SCpnt, DID_ERROR);
2079 	    break;
2080 
2081 	default:
2082 	    printk(KERN_ERR "scsi%d.%c: PHASE_CONNECTED, SSR %02X?\n",
2083 		    host->host->host_no, acornscsi_target(host), ssr);
2084 	    acornscsi_dumplog(host, host->SCpnt ? host->SCpnt->device->id : 8);
2085 	    acornscsi_abortcmd(host, host->SCpnt->tag);
2086 	}
2087 	return INTR_PROCESSING;
2088 
2089     case PHASE_MSGOUT:			/* STATE: connected & sent IDENTIFY message	*/
2090 	/*
2091 	 * SCSI standard says that MESSAGE OUT phases can be followed by a
2092 	 * DATA phase, STATUS phase, MESSAGE IN phase or COMMAND phase
2093 	 */
2094 	switch (ssr) {
2095 	case 0x8a:			/* -> PHASE_COMMAND, PHASE_COMMANDPAUSED	*/
2096 	case 0x1a:			/* -> PHASE_COMMAND, PHASE_COMMANDPAUSED	*/
2097 	    /* MESSAGE OUT -> COMMAND */
2098 	    acornscsi_sendcommand(host);
2099 	    break;
2100 
2101 	case 0x8b:			/* -> PHASE_STATUS				*/
2102 	case 0x1b:			/* -> PHASE_STATUS				*/
2103 	    /* MESSAGE OUT -> STATUS */
2104 	    acornscsi_readstatusbyte(host);
2105 	    host->scsi.phase = PHASE_STATUSIN;
2106 	    break;
2107 
2108 	case 0x8e:			/* -> PHASE_MSGOUT				*/
2109 	    /* MESSAGE_OUT(MESSAGE_IN) ->MESSAGE OUT */
2110 	    acornscsi_sendmessage(host);
2111 	    break;
2112 
2113 	case 0x4f:			/* -> PHASE_MSGIN, PHASE_DISCONNECT		*/
2114 	case 0x1f:			/* -> PHASE_MSGIN, PHASE_DISCONNECT		*/
2115 	    /* MESSAGE OUT -> MESSAGE IN */
2116 	    acornscsi_message(host);
2117 	    break;
2118 
2119 	default:
2120 	    printk(KERN_ERR "scsi%d.%c: PHASE_MSGOUT, SSR %02X?\n",
2121 		    host->host->host_no, acornscsi_target(host), ssr);
2122 	    acornscsi_dumplog(host, host->SCpnt ? host->SCpnt->device->id : 8);
2123 	}
2124 	return INTR_PROCESSING;
2125 
2126     case PHASE_COMMAND: 		/* STATE: connected & command sent		*/
2127 	switch (ssr) {
2128 	case 0x18:			/* -> PHASE_DATAOUT				*/
2129 	    /* COMMAND -> DATA OUT */
2130 	    if (host->scsi.SCp.sent_command != host->SCpnt->cmd_len)
2131 		acornscsi_abortcmd(host, host->SCpnt->tag);
2132 	    acornscsi_dma_setup(host, DMA_OUT);
2133 	    if (!acornscsi_starttransfer(host))
2134 		acornscsi_abortcmd(host, host->SCpnt->tag);
2135 	    host->scsi.phase = PHASE_DATAOUT;
2136 	    return INTR_IDLE;
2137 
2138 	case 0x19:			/* -> PHASE_DATAIN				*/
2139 	    /* COMMAND -> DATA IN */
2140 	    if (host->scsi.SCp.sent_command != host->SCpnt->cmd_len)
2141 		acornscsi_abortcmd(host, host->SCpnt->tag);
2142 	    acornscsi_dma_setup(host, DMA_IN);
2143 	    if (!acornscsi_starttransfer(host))
2144 		acornscsi_abortcmd(host, host->SCpnt->tag);
2145 	    host->scsi.phase = PHASE_DATAIN;
2146 	    return INTR_IDLE;
2147 
2148 	case 0x1b:			/* -> PHASE_STATUS				*/
2149 	    /* COMMAND -> STATUS */
2150 	    acornscsi_readstatusbyte(host);
2151 	    host->scsi.phase = PHASE_STATUSIN;
2152 	    break;
2153 
2154 	case 0x1e:			/* -> PHASE_MSGOUT				*/
2155 	    /* COMMAND -> MESSAGE OUT */
2156 	    acornscsi_sendmessage(host);
2157 	    break;
2158 
2159 	case 0x1f:			/* -> PHASE_MSGIN, PHASE_DISCONNECT		*/
2160 	    /* COMMAND -> MESSAGE IN */
2161 	    acornscsi_message(host);
2162 	    break;
2163 
2164 	default:
2165 	    printk(KERN_ERR "scsi%d.%c: PHASE_COMMAND, SSR %02X?\n",
2166 		    host->host->host_no, acornscsi_target(host), ssr);
2167 	    acornscsi_dumplog(host, host->SCpnt ? host->SCpnt->device->id : 8);
2168 	}
2169 	return INTR_PROCESSING;
2170 
2171     case PHASE_DISCONNECT:		/* STATE: connected, received DISCONNECT msg	*/
2172 	if (ssr == 0x85) {		/* -> PHASE_IDLE				*/
2173 	    host->scsi.disconnectable = 1;
2174 	    host->scsi.reconnected.tag = 0;
2175 	    host->scsi.phase = PHASE_IDLE;
2176 	    host->stats.disconnects += 1;
2177 	} else {
2178 	    printk(KERN_ERR "scsi%d.%c: PHASE_DISCONNECT, SSR %02X instead of disconnect?\n",
2179 		    host->host->host_no, acornscsi_target(host), ssr);
2180 	    acornscsi_dumplog(host, host->SCpnt ? host->SCpnt->device->id : 8);
2181 	}
2182 	return INTR_NEXT_COMMAND;
2183 
2184     case PHASE_IDLE:			/* STATE: disconnected				*/
2185 	if (ssr == 0x81)		/* -> PHASE_RECONNECTED or PHASE_ABORTED	*/
2186 	    acornscsi_reconnect(host);
2187 	else {
2188 	    printk(KERN_ERR "scsi%d.%c: PHASE_IDLE, SSR %02X while idle?\n",
2189 		    host->host->host_no, acornscsi_target(host), ssr);
2190 	    acornscsi_dumplog(host, host->SCpnt ? host->SCpnt->device->id : 8);
2191 	}
2192 	return INTR_PROCESSING;
2193 
2194     case PHASE_RECONNECTED:		/* STATE: device reconnected to initiator	*/
2195 	/*
2196 	 * Command reconnected - if MESGIN, get message - it may be
2197 	 * the tag.  If not, get command out of disconnected queue
2198 	 */
2199 	/*
2200 	 * If we reconnected and we're not in MESSAGE IN phase after IDENTIFY,
2201 	 * reconnect I_T_L command
2202 	 */
2203 	if (ssr != 0x8f && !acornscsi_reconnect_finish(host))
2204 	    return INTR_IDLE;
2205 	ADD_STATUS(host->SCpnt->device->id, ssr, host->scsi.phase, in_irq);
2206 	switch (ssr) {
2207 	case 0x88:			/* data out phase				*/
2208 					/* -> PHASE_DATAOUT				*/
2209 	    /* MESSAGE IN -> DATA OUT */
2210 	    acornscsi_dma_setup(host, DMA_OUT);
2211 	    if (!acornscsi_starttransfer(host))
2212 		acornscsi_abortcmd(host, host->SCpnt->tag);
2213 	    host->scsi.phase = PHASE_DATAOUT;
2214 	    return INTR_IDLE;
2215 
2216 	case 0x89:			/* data in phase				*/
2217 					/* -> PHASE_DATAIN				*/
2218 	    /* MESSAGE IN -> DATA IN */
2219 	    acornscsi_dma_setup(host, DMA_IN);
2220 	    if (!acornscsi_starttransfer(host))
2221 		acornscsi_abortcmd(host, host->SCpnt->tag);
2222 	    host->scsi.phase = PHASE_DATAIN;
2223 	    return INTR_IDLE;
2224 
2225 	case 0x8a:			/* command out					*/
2226 	    /* MESSAGE IN -> COMMAND */
2227 	    acornscsi_sendcommand(host);/* -> PHASE_COMMAND, PHASE_COMMANDPAUSED	*/
2228 	    break;
2229 
2230 	case 0x8b:			/* status in					*/
2231 					/* -> PHASE_STATUSIN				*/
2232 	    /* MESSAGE IN -> STATUS */
2233 	    acornscsi_readstatusbyte(host);
2234 	    host->scsi.phase = PHASE_STATUSIN;
2235 	    break;
2236 
2237 	case 0x8e:			/* message out					*/
2238 					/* -> PHASE_MSGOUT				*/
2239 	    /* MESSAGE IN -> MESSAGE OUT */
2240 	    acornscsi_sendmessage(host);
2241 	    break;
2242 
2243 	case 0x8f:			/* message in					*/
2244 	    acornscsi_message(host);	/* -> PHASE_MSGIN, PHASE_DISCONNECT		*/
2245 	    break;
2246 
2247 	default:
2248 	    printk(KERN_ERR "scsi%d.%c: PHASE_RECONNECTED, SSR %02X after reconnect?\n",
2249 		    host->host->host_no, acornscsi_target(host), ssr);
2250 	    acornscsi_dumplog(host, host->SCpnt ? host->SCpnt->device->id : 8);
2251 	}
2252 	return INTR_PROCESSING;
2253 
2254     case PHASE_DATAIN:			/* STATE: transferred data in			*/
2255 	/*
2256 	 * This is simple - if we disconnect then the DMA address & count is
2257 	 * correct.
2258 	 */
2259 	switch (ssr) {
2260 	case 0x19:			/* -> PHASE_DATAIN				*/
2261 	case 0x89:			/* -> PHASE_DATAIN				*/
2262 	    acornscsi_abortcmd(host, host->SCpnt->tag);
2263 	    return INTR_IDLE;
2264 
2265 	case 0x1b:			/* -> PHASE_STATUSIN				*/
2266 	case 0x4b:			/* -> PHASE_STATUSIN				*/
2267 	case 0x8b:			/* -> PHASE_STATUSIN				*/
2268 	    /* DATA IN -> STATUS */
2269 	    host->scsi.SCp.scsi_xferred = scsi_bufflen(host->SCpnt) -
2270 					  acornscsi_sbic_xfcount(host);
2271 	    acornscsi_dma_stop(host);
2272 	    acornscsi_readstatusbyte(host);
2273 	    host->scsi.phase = PHASE_STATUSIN;
2274 	    break;
2275 
2276 	case 0x1e:			/* -> PHASE_MSGOUT				*/
2277 	case 0x4e:			/* -> PHASE_MSGOUT				*/
2278 	case 0x8e:			/* -> PHASE_MSGOUT				*/
2279 	    /* DATA IN -> MESSAGE OUT */
2280 	    host->scsi.SCp.scsi_xferred = scsi_bufflen(host->SCpnt) -
2281 					  acornscsi_sbic_xfcount(host);
2282 	    acornscsi_dma_stop(host);
2283 	    acornscsi_sendmessage(host);
2284 	    break;
2285 
2286 	case 0x1f:			/* message in					*/
2287 	case 0x4f:			/* message in					*/
2288 	case 0x8f:			/* message in					*/
2289 	    /* DATA IN -> MESSAGE IN */
2290 	    host->scsi.SCp.scsi_xferred = scsi_bufflen(host->SCpnt) -
2291 					  acornscsi_sbic_xfcount(host);
2292 	    acornscsi_dma_stop(host);
2293 	    acornscsi_message(host);	/* -> PHASE_MSGIN, PHASE_DISCONNECT		*/
2294 	    break;
2295 
2296 	default:
2297 	    printk(KERN_ERR "scsi%d.%c: PHASE_DATAIN, SSR %02X?\n",
2298 		    host->host->host_no, acornscsi_target(host), ssr);
2299 	    acornscsi_dumplog(host, host->SCpnt ? host->SCpnt->device->id : 8);
2300 	}
2301 	return INTR_PROCESSING;
2302 
2303     case PHASE_DATAOUT: 		/* STATE: transferred data out			*/
2304 	/*
2305 	 * This is more complicated - if we disconnect, the DMA could be 12
2306 	 * bytes ahead of us.  We need to correct this.
2307 	 */
2308 	switch (ssr) {
2309 	case 0x18:			/* -> PHASE_DATAOUT				*/
2310 	case 0x88:			/* -> PHASE_DATAOUT				*/
2311 	    acornscsi_abortcmd(host, host->SCpnt->tag);
2312 	    return INTR_IDLE;
2313 
2314 	case 0x1b:			/* -> PHASE_STATUSIN				*/
2315 	case 0x4b:			/* -> PHASE_STATUSIN				*/
2316 	case 0x8b:			/* -> PHASE_STATUSIN				*/
2317 	    /* DATA OUT -> STATUS */
2318 	    host->scsi.SCp.scsi_xferred = scsi_bufflen(host->SCpnt) -
2319 					  acornscsi_sbic_xfcount(host);
2320 	    acornscsi_dma_stop(host);
2321 	    acornscsi_dma_adjust(host);
2322 	    acornscsi_readstatusbyte(host);
2323 	    host->scsi.phase = PHASE_STATUSIN;
2324 	    break;
2325 
2326 	case 0x1e:			/* -> PHASE_MSGOUT				*/
2327 	case 0x4e:			/* -> PHASE_MSGOUT				*/
2328 	case 0x8e:			/* -> PHASE_MSGOUT				*/
2329 	    /* DATA OUT -> MESSAGE OUT */
2330 	    host->scsi.SCp.scsi_xferred = scsi_bufflen(host->SCpnt) -
2331 					  acornscsi_sbic_xfcount(host);
2332 	    acornscsi_dma_stop(host);
2333 	    acornscsi_dma_adjust(host);
2334 	    acornscsi_sendmessage(host);
2335 	    break;
2336 
2337 	case 0x1f:			/* message in					*/
2338 	case 0x4f:			/* message in					*/
2339 	case 0x8f:			/* message in					*/
2340 	    /* DATA OUT -> MESSAGE IN */
2341 	    host->scsi.SCp.scsi_xferred = scsi_bufflen(host->SCpnt) -
2342 					  acornscsi_sbic_xfcount(host);
2343 	    acornscsi_dma_stop(host);
2344 	    acornscsi_dma_adjust(host);
2345 	    acornscsi_message(host);	/* -> PHASE_MSGIN, PHASE_DISCONNECT		*/
2346 	    break;
2347 
2348 	default:
2349 	    printk(KERN_ERR "scsi%d.%c: PHASE_DATAOUT, SSR %02X?\n",
2350 		    host->host->host_no, acornscsi_target(host), ssr);
2351 	    acornscsi_dumplog(host, host->SCpnt ? host->SCpnt->device->id : 8);
2352 	}
2353 	return INTR_PROCESSING;
2354 
2355     case PHASE_STATUSIN:		/* STATE: status in complete			*/
2356 	switch (ssr) {
2357 	case 0x1f:			/* -> PHASE_MSGIN, PHASE_DONE, PHASE_DISCONNECT */
2358 	case 0x8f:			/* -> PHASE_MSGIN, PHASE_DONE, PHASE_DISCONNECT */
2359 	    /* STATUS -> MESSAGE IN */
2360 	    acornscsi_message(host);
2361 	    break;
2362 
2363 	case 0x1e:			/* -> PHASE_MSGOUT				*/
2364 	case 0x8e:			/* -> PHASE_MSGOUT				*/
2365 	    /* STATUS -> MESSAGE OUT */
2366 	    acornscsi_sendmessage(host);
2367 	    break;
2368 
2369 	default:
2370 	    printk(KERN_ERR "scsi%d.%c: PHASE_STATUSIN, SSR %02X instead of MESSAGE_IN?\n",
2371 		    host->host->host_no, acornscsi_target(host), ssr);
2372 	    acornscsi_dumplog(host, host->SCpnt ? host->SCpnt->device->id : 8);
2373 	}
2374 	return INTR_PROCESSING;
2375 
2376     case PHASE_MSGIN:			/* STATE: message in				*/
2377 	switch (ssr) {
2378 	case 0x1e:			/* -> PHASE_MSGOUT				*/
2379 	case 0x4e:			/* -> PHASE_MSGOUT				*/
2380 	case 0x8e:			/* -> PHASE_MSGOUT				*/
2381 	    /* MESSAGE IN -> MESSAGE OUT */
2382 	    acornscsi_sendmessage(host);
2383 	    break;
2384 
2385 	case 0x1f:			/* -> PHASE_MSGIN, PHASE_DONE, PHASE_DISCONNECT */
2386 	case 0x2f:
2387 	case 0x4f:
2388 	case 0x8f:
2389 	    acornscsi_message(host);
2390 	    break;
2391 
2392 	case 0x85:
2393 	    printk("scsi%d.%c: strange message in disconnection\n",
2394 		host->host->host_no, acornscsi_target(host));
2395 	    acornscsi_dumplog(host, host->SCpnt ? host->SCpnt->device->id : 8);
2396 	    acornscsi_done(host, &host->SCpnt, DID_ERROR);
2397 	    break;
2398 
2399 	default:
2400 	    printk(KERN_ERR "scsi%d.%c: PHASE_MSGIN, SSR %02X after message in?\n",
2401 		    host->host->host_no, acornscsi_target(host), ssr);
2402 	    acornscsi_dumplog(host, host->SCpnt ? host->SCpnt->device->id : 8);
2403 	}
2404 	return INTR_PROCESSING;
2405 
2406     case PHASE_DONE:			/* STATE: received status & message		*/
2407 	switch (ssr) {
2408 	case 0x85:			/* -> PHASE_IDLE				*/
2409 	    acornscsi_done(host, &host->SCpnt, DID_OK);
2410 	    return INTR_NEXT_COMMAND;
2411 
2412 	case 0x1e:
2413 	case 0x8e:
2414 	    acornscsi_sendmessage(host);
2415 	    break;
2416 
2417 	default:
2418 	    printk(KERN_ERR "scsi%d.%c: PHASE_DONE, SSR %02X instead of disconnect?\n",
2419 		    host->host->host_no, acornscsi_target(host), ssr);
2420 	    acornscsi_dumplog(host, host->SCpnt ? host->SCpnt->device->id : 8);
2421 	}
2422 	return INTR_PROCESSING;
2423 
2424     case PHASE_ABORTED:
2425 	switch (ssr) {
2426 	case 0x85:
2427 	    if (host->SCpnt)
2428 		acornscsi_done(host, &host->SCpnt, DID_ABORT);
2429 	    else {
2430 		clear_bit(host->scsi.reconnected.target * 8 + host->scsi.reconnected.lun,
2431 			  host->busyluns);
2432 		host->scsi.phase = PHASE_IDLE;
2433 	    }
2434 	    return INTR_NEXT_COMMAND;
2435 
2436 	case 0x1e:
2437 	case 0x2e:
2438 	case 0x4e:
2439 	case 0x8e:
2440 	    acornscsi_sendmessage(host);
2441 	    break;
2442 
2443 	default:
2444 	    printk(KERN_ERR "scsi%d.%c: PHASE_ABORTED, SSR %02X?\n",
2445 		    host->host->host_no, acornscsi_target(host), ssr);
2446 	    acornscsi_dumplog(host, host->SCpnt ? host->SCpnt->device->id : 8);
2447 	}
2448 	return INTR_PROCESSING;
2449 
2450     default:
2451 	printk(KERN_ERR "scsi%d.%c: unknown driver phase %d\n",
2452 		host->host->host_no, acornscsi_target(host), ssr);
2453 	acornscsi_dumplog(host, host->SCpnt ? host->SCpnt->device->id : 8);
2454     }
2455     return INTR_PROCESSING;
2456 }
2457 
2458 /*
2459  * Prototype: void acornscsi_intr(int irq, void *dev_id)
2460  * Purpose  : handle interrupts from Acorn SCSI card
2461  * Params   : irq    - interrupt number
2462  *	      dev_id - device specific data (AS_Host structure)
2463  */
2464 static irqreturn_t
2465 acornscsi_intr(int irq, void *dev_id)
2466 {
2467     AS_Host *host = (AS_Host *)dev_id;
2468     intr_ret_t ret;
2469     int iostatus;
2470     int in_irq = 0;
2471 
2472     do {
2473 	ret = INTR_IDLE;
2474 
2475 	iostatus = readb(host->fast + INT_REG);
2476 
2477 	if (iostatus & 2) {
2478 	    acornscsi_dma_intr(host);
2479 	    iostatus = readb(host->fast + INT_REG);
2480 	}
2481 
2482 	if (iostatus & 8)
2483 	    ret = acornscsi_sbicintr(host, in_irq);
2484 
2485 	/*
2486 	 * If we have a transfer pending, start it.
2487 	 * Only start it if the interface has already started transferring
2488 	 * it's data
2489 	 */
2490 	if (host->dma.xfer_required)
2491 	    acornscsi_dma_xfer(host);
2492 
2493 	if (ret == INTR_NEXT_COMMAND)
2494 	    ret = acornscsi_kick(host);
2495 
2496 	in_irq = 1;
2497     } while (ret != INTR_IDLE);
2498 
2499     return IRQ_HANDLED;
2500 }
2501 
2502 /*=============================================================================================
2503  * Interfaces between interrupt handler and rest of scsi code
2504  */
2505 
2506 /*
2507  * Function : acornscsi_queuecmd(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *))
2508  * Purpose  : queues a SCSI command
2509  * Params   : cmd  - SCSI command
2510  *	      done - function called on completion, with pointer to command descriptor
2511  * Returns  : 0, or < 0 on error.
2512  */
2513 static int acornscsi_queuecmd_lck(struct scsi_cmnd *SCpnt,
2514 		       void (*done)(struct scsi_cmnd *))
2515 {
2516     AS_Host *host = (AS_Host *)SCpnt->device->host->hostdata;
2517 
2518     if (!done) {
2519 	/* there should be some way of rejecting errors like this without panicing... */
2520 	panic("scsi%d: queuecommand called with NULL done function [cmd=%p]",
2521 		host->host->host_no, SCpnt);
2522 	return -EINVAL;
2523     }
2524 
2525 #if (DEBUG & DEBUG_NO_WRITE)
2526     if (acornscsi_cmdtype(SCpnt->cmnd[0]) == CMD_WRITE && (NO_WRITE & (1 << SCpnt->device->id))) {
2527 	printk(KERN_CRIT "scsi%d.%c: WRITE attempted with NO_WRITE flag set\n",
2528 	    host->host->host_no, '0' + SCpnt->device->id);
2529 	SCpnt->result = DID_NO_CONNECT << 16;
2530 	done(SCpnt);
2531 	return 0;
2532     }
2533 #endif
2534 
2535     SCpnt->scsi_done = done;
2536     SCpnt->host_scribble = NULL;
2537     SCpnt->result = 0;
2538     SCpnt->tag = 0;
2539     SCpnt->SCp.phase = (int)acornscsi_datadirection(SCpnt->cmnd[0]);
2540     SCpnt->SCp.sent_command = 0;
2541     SCpnt->SCp.scsi_xferred = 0;
2542 
2543     init_SCp(SCpnt);
2544 
2545     host->stats.queues += 1;
2546 
2547     {
2548 	unsigned long flags;
2549 
2550 	if (!queue_add_cmd_ordered(&host->queues.issue, SCpnt)) {
2551 	    SCpnt->result = DID_ERROR << 16;
2552 	    done(SCpnt);
2553 	    return 0;
2554 	}
2555 	local_irq_save(flags);
2556 	if (host->scsi.phase == PHASE_IDLE)
2557 	    acornscsi_kick(host);
2558 	local_irq_restore(flags);
2559     }
2560     return 0;
2561 }
2562 
2563 DEF_SCSI_QCMD(acornscsi_queuecmd)
2564 
2565 /*
2566  * Prototype: void acornscsi_reportstatus(struct scsi_cmnd **SCpntp1, struct scsi_cmnd **SCpntp2, int result)
2567  * Purpose  : pass a result to *SCpntp1, and check if *SCpntp1 = *SCpntp2
2568  * Params   : SCpntp1 - pointer to command to return
2569  *	      SCpntp2 - pointer to command to check
2570  *	      result  - result to pass back to mid-level done function
2571  * Returns  : *SCpntp2 = NULL if *SCpntp1 is the same command structure as *SCpntp2.
2572  */
2573 static inline void acornscsi_reportstatus(struct scsi_cmnd **SCpntp1,
2574 					  struct scsi_cmnd **SCpntp2,
2575 					  int result)
2576 {
2577 	struct scsi_cmnd *SCpnt = *SCpntp1;
2578 
2579     if (SCpnt) {
2580 	*SCpntp1 = NULL;
2581 
2582 	SCpnt->result = result;
2583 	SCpnt->scsi_done(SCpnt);
2584     }
2585 
2586     if (SCpnt == *SCpntp2)
2587 	*SCpntp2 = NULL;
2588 }
2589 
2590 enum res_abort { res_not_running, res_success, res_success_clear, res_snooze };
2591 
2592 /*
2593  * Prototype: enum res acornscsi_do_abort(struct scsi_cmnd *SCpnt)
2594  * Purpose  : abort a command on this host
2595  * Params   : SCpnt - command to abort
2596  * Returns  : our abort status
2597  */
2598 static enum res_abort acornscsi_do_abort(AS_Host *host, struct scsi_cmnd *SCpnt)
2599 {
2600 	enum res_abort res = res_not_running;
2601 
2602 	if (queue_remove_cmd(&host->queues.issue, SCpnt)) {
2603 		/*
2604 		 * The command was on the issue queue, and has not been
2605 		 * issued yet.  We can remove the command from the queue,
2606 		 * and acknowledge the abort.  Neither the devices nor the
2607 		 * interface know about the command.
2608 		 */
2609 //#if (DEBUG & DEBUG_ABORT)
2610 		printk("on issue queue ");
2611 //#endif
2612 		res = res_success;
2613 	} else if (queue_remove_cmd(&host->queues.disconnected, SCpnt)) {
2614 		/*
2615 		 * The command was on the disconnected queue.  Simply
2616 		 * acknowledge the abort condition, and when the target
2617 		 * reconnects, we will give it an ABORT message.  The
2618 		 * target should then disconnect, and we will clear
2619 		 * the busylun bit.
2620 		 */
2621 //#if (DEBUG & DEBUG_ABORT)
2622 		printk("on disconnected queue ");
2623 //#endif
2624 		res = res_success;
2625 	} else if (host->SCpnt == SCpnt) {
2626 		unsigned long flags;
2627 
2628 //#if (DEBUG & DEBUG_ABORT)
2629 		printk("executing ");
2630 //#endif
2631 
2632 		local_irq_save(flags);
2633 		switch (host->scsi.phase) {
2634 		/*
2635 		 * If the interface is idle, and the command is 'disconnectable',
2636 		 * then it is the same as on the disconnected queue.  We simply
2637 		 * remove all traces of the command.  When the target reconnects,
2638 		 * we will give it an ABORT message since the command could not
2639 		 * be found.  When the target finally disconnects, we will clear
2640 		 * the busylun bit.
2641 		 */
2642 		case PHASE_IDLE:
2643 			if (host->scsi.disconnectable) {
2644 				host->scsi.disconnectable = 0;
2645 				host->SCpnt = NULL;
2646 				res = res_success;
2647 			}
2648 			break;
2649 
2650 		/*
2651 		 * If the command has connected and done nothing further,
2652 		 * simply force a disconnect.  We also need to clear the
2653 		 * busylun bit.
2654 		 */
2655 		case PHASE_CONNECTED:
2656 			sbic_arm_write(host, SBIC_CMND, CMND_DISCONNECT);
2657 			host->SCpnt = NULL;
2658 			res = res_success_clear;
2659 			break;
2660 
2661 		default:
2662 			acornscsi_abortcmd(host, host->SCpnt->tag);
2663 			res = res_snooze;
2664 		}
2665 		local_irq_restore(flags);
2666 	} else if (host->origSCpnt == SCpnt) {
2667 		/*
2668 		 * The command will be executed next, but a command
2669 		 * is currently using the interface.  This is similar to
2670 		 * being on the issue queue, except the busylun bit has
2671 		 * been set.
2672 		 */
2673 		host->origSCpnt = NULL;
2674 //#if (DEBUG & DEBUG_ABORT)
2675 		printk("waiting for execution ");
2676 //#endif
2677 		res = res_success_clear;
2678 	} else
2679 		printk("unknown ");
2680 
2681 	return res;
2682 }
2683 
2684 /*
2685  * Prototype: int acornscsi_abort(struct scsi_cmnd *SCpnt)
2686  * Purpose  : abort a command on this host
2687  * Params   : SCpnt - command to abort
2688  * Returns  : one of SCSI_ABORT_ macros
2689  */
2690 int acornscsi_abort(struct scsi_cmnd *SCpnt)
2691 {
2692 	AS_Host *host = (AS_Host *) SCpnt->device->host->hostdata;
2693 	int result;
2694 
2695 	host->stats.aborts += 1;
2696 
2697 #if (DEBUG & DEBUG_ABORT)
2698 	{
2699 		int asr, ssr;
2700 		asr = sbic_arm_read(host, SBIC_ASR);
2701 		ssr = sbic_arm_read(host, SBIC_SSR);
2702 
2703 		printk(KERN_WARNING "acornscsi_abort: ");
2704 		print_sbic_status(asr, ssr, host->scsi.phase);
2705 		acornscsi_dumplog(host, SCpnt->device->id);
2706 	}
2707 #endif
2708 
2709 	printk("scsi%d: ", host->host->host_no);
2710 
2711 	switch (acornscsi_do_abort(host, SCpnt)) {
2712 	/*
2713 	 * We managed to find the command and cleared it out.
2714 	 * We do not expect the command to be executing on the
2715 	 * target, but we have set the busylun bit.
2716 	 */
2717 	case res_success_clear:
2718 //#if (DEBUG & DEBUG_ABORT)
2719 		printk("clear ");
2720 //#endif
2721 		clear_bit(SCpnt->device->id * 8 + SCpnt->device->lun, host->busyluns);
2722 
2723 	/*
2724 	 * We found the command, and cleared it out.  Either
2725 	 * the command is still known to be executing on the
2726 	 * target, or the busylun bit is not set.
2727 	 */
2728 	case res_success:
2729 //#if (DEBUG & DEBUG_ABORT)
2730 		printk("success\n");
2731 //#endif
2732 		result = SUCCESS;
2733 		break;
2734 
2735 	/*
2736 	 * We did find the command, but unfortunately we couldn't
2737 	 * unhook it from ourselves.  Wait some more, and if it
2738 	 * still doesn't complete, reset the interface.
2739 	 */
2740 	case res_snooze:
2741 //#if (DEBUG & DEBUG_ABORT)
2742 		printk("snooze\n");
2743 //#endif
2744 		result = FAILED;
2745 		break;
2746 
2747 	/*
2748 	 * The command could not be found (either because it completed,
2749 	 * or it got dropped.
2750 	 */
2751 	default:
2752 	case res_not_running:
2753 		acornscsi_dumplog(host, SCpnt->device->id);
2754 		result = FAILED;
2755 //#if (DEBUG & DEBUG_ABORT)
2756 		printk("not running\n");
2757 //#endif
2758 		break;
2759 	}
2760 
2761 	return result;
2762 }
2763 
2764 /*
2765  * Prototype: int acornscsi_reset(struct scsi_cmnd *SCpnt)
2766  * Purpose  : reset a command on this host/reset this host
2767  * Params   : SCpnt  - command causing reset
2768  * Returns  : one of SCSI_RESET_ macros
2769  */
2770 int acornscsi_bus_reset(struct scsi_cmnd *SCpnt)
2771 {
2772 	AS_Host *host = (AS_Host *)SCpnt->device->host->hostdata;
2773 	struct scsi_cmnd *SCptr;
2774 
2775     host->stats.resets += 1;
2776 
2777 #if (DEBUG & DEBUG_RESET)
2778     {
2779 	int asr, ssr;
2780 
2781 	asr = sbic_arm_read(host, SBIC_ASR);
2782 	ssr = sbic_arm_read(host, SBIC_SSR);
2783 
2784 	printk(KERN_WARNING "acornscsi_reset: ");
2785 	print_sbic_status(asr, ssr, host->scsi.phase);
2786 	acornscsi_dumplog(host, SCpnt->device->id);
2787     }
2788 #endif
2789 
2790     acornscsi_dma_stop(host);
2791 
2792     /*
2793      * do hard reset.  This resets all devices on this host, and so we
2794      * must set the reset status on all commands.
2795      */
2796     acornscsi_resetcard(host);
2797 
2798     while ((SCptr = queue_remove(&host->queues.disconnected)) != NULL)
2799 	;
2800 
2801     return SUCCESS;
2802 }
2803 
2804 /*==============================================================================================
2805  * initialisation & miscellaneous support
2806  */
2807 
2808 /*
2809  * Function: char *acornscsi_info(struct Scsi_Host *host)
2810  * Purpose : return a string describing this interface
2811  * Params  : host - host to give information on
2812  * Returns : a constant string
2813  */
2814 const
2815 char *acornscsi_info(struct Scsi_Host *host)
2816 {
2817     static char string[100], *p;
2818 
2819     p = string;
2820 
2821     p += sprintf(string, "%s at port %08lX irq %d v%d.%d.%d"
2822 #ifdef CONFIG_SCSI_ACORNSCSI_SYNC
2823     " SYNC"
2824 #endif
2825 #ifdef CONFIG_SCSI_ACORNSCSI_TAGGED_QUEUE
2826     " TAG"
2827 #endif
2828 #ifdef CONFIG_SCSI_ACORNSCSI_LINK
2829     " LINK"
2830 #endif
2831 #if (DEBUG & DEBUG_NO_WRITE)
2832     " NOWRITE (" __stringify(NO_WRITE) ")"
2833 #endif
2834 		, host->hostt->name, host->io_port, host->irq,
2835 		VER_MAJOR, VER_MINOR, VER_PATCH);
2836     return string;
2837 }
2838 
2839 static int acornscsi_show_info(struct seq_file *m, struct Scsi_Host *instance)
2840 {
2841     int devidx;
2842     struct scsi_device *scd;
2843     AS_Host *host;
2844 
2845     host  = (AS_Host *)instance->hostdata;
2846 
2847     seq_printf(m, "AcornSCSI driver v%d.%d.%d"
2848 #ifdef CONFIG_SCSI_ACORNSCSI_SYNC
2849     " SYNC"
2850 #endif
2851 #ifdef CONFIG_SCSI_ACORNSCSI_TAGGED_QUEUE
2852     " TAG"
2853 #endif
2854 #ifdef CONFIG_SCSI_ACORNSCSI_LINK
2855     " LINK"
2856 #endif
2857 #if (DEBUG & DEBUG_NO_WRITE)
2858     " NOWRITE (" __stringify(NO_WRITE) ")"
2859 #endif
2860 		"\n\n", VER_MAJOR, VER_MINOR, VER_PATCH);
2861 
2862     seq_printf(m,	"SBIC: WD33C93A  Address: %p    IRQ : %d\n",
2863 			host->base + SBIC_REGIDX, host->scsi.irq);
2864 #ifdef USE_DMAC
2865     seq_printf(m,	"DMAC: uPC71071  Address: %p  IRQ : %d\n\n",
2866 			host->base + DMAC_OFFSET, host->scsi.irq);
2867 #endif
2868 
2869     seq_printf(m,	"Statistics:\n"
2870 			"Queued commands: %-10u    Issued commands: %-10u\n"
2871 			"Done commands  : %-10u    Reads          : %-10u\n"
2872 			"Writes         : %-10u    Others         : %-10u\n"
2873 			"Disconnects    : %-10u    Aborts         : %-10u\n"
2874 			"Resets         : %-10u\n\nLast phases:",
2875 			host->stats.queues,		host->stats.removes,
2876 			host->stats.fins,		host->stats.reads,
2877 			host->stats.writes,		host->stats.miscs,
2878 			host->stats.disconnects,	host->stats.aborts,
2879 			host->stats.resets);
2880 
2881     for (devidx = 0; devidx < 9; devidx ++) {
2882 	unsigned int statptr, prev;
2883 
2884 	seq_printf(m, "\n%c:", devidx == 8 ? 'H' : ('0' + devidx));
2885 	statptr = host->status_ptr[devidx] - 10;
2886 
2887 	if ((signed int)statptr < 0)
2888 	    statptr += STATUS_BUFFER_SIZE;
2889 
2890 	prev = host->status[devidx][statptr].when;
2891 
2892 	for (; statptr != host->status_ptr[devidx]; statptr = (statptr + 1) & (STATUS_BUFFER_SIZE - 1)) {
2893 	    if (host->status[devidx][statptr].when) {
2894 		seq_printf(m, "%c%02X:%02X+%2ld",
2895 			host->status[devidx][statptr].irq ? '-' : ' ',
2896 			host->status[devidx][statptr].ph,
2897 			host->status[devidx][statptr].ssr,
2898 			(host->status[devidx][statptr].when - prev) < 100 ?
2899 				(host->status[devidx][statptr].when - prev) : 99);
2900 		prev = host->status[devidx][statptr].when;
2901 	    }
2902 	}
2903     }
2904 
2905     seq_printf(m, "\nAttached devices:\n");
2906 
2907     shost_for_each_device(scd, instance) {
2908 	seq_printf(m, "Device/Lun TaggedQ      Sync\n");
2909 	seq_printf(m, "     %d/%d   ", scd->id, scd->lun);
2910 	if (scd->tagged_supported)
2911 		seq_printf(m, "%3sabled(%3d) ",
2912 			     scd->simple_tags ? "en" : "dis",
2913 			     scd->current_tag);
2914 	else
2915 		seq_printf(m, "unsupported  ");
2916 
2917 	if (host->device[scd->id].sync_xfer & 15)
2918 		seq_printf(m, "offset %d, %d ns\n",
2919 			     host->device[scd->id].sync_xfer & 15,
2920 			     acornscsi_getperiod(host->device[scd->id].sync_xfer));
2921 	else
2922 		seq_printf(m, "async\n");
2923 
2924     }
2925     return 0;
2926 }
2927 
2928 static struct scsi_host_template acornscsi_template = {
2929 	.module			= THIS_MODULE,
2930 	.show_info		= acornscsi_show_info,
2931 	.name			= "AcornSCSI",
2932 	.info			= acornscsi_info,
2933 	.queuecommand		= acornscsi_queuecmd,
2934 	.eh_abort_handler	= acornscsi_abort,
2935 	.eh_bus_reset_handler	= acornscsi_bus_reset,
2936 	.can_queue		= 16,
2937 	.this_id		= 7,
2938 	.sg_tablesize		= SG_ALL,
2939 	.cmd_per_lun		= 2,
2940 	.use_clustering		= DISABLE_CLUSTERING,
2941 	.proc_name		= "acornscsi",
2942 };
2943 
2944 static int acornscsi_probe(struct expansion_card *ec, const struct ecard_id *id)
2945 {
2946 	struct Scsi_Host *host;
2947 	AS_Host *ashost;
2948 	int ret;
2949 
2950 	ret = ecard_request_resources(ec);
2951 	if (ret)
2952 		goto out;
2953 
2954 	host = scsi_host_alloc(&acornscsi_template, sizeof(AS_Host));
2955 	if (!host) {
2956 		ret = -ENOMEM;
2957 		goto out_release;
2958 	}
2959 
2960 	ashost = (AS_Host *)host->hostdata;
2961 
2962 	ashost->base = ecardm_iomap(ec, ECARD_RES_MEMC, 0, 0);
2963 	ashost->fast = ecardm_iomap(ec, ECARD_RES_IOCFAST, 0, 0);
2964 	if (!ashost->base || !ashost->fast)
2965 		goto out_put;
2966 
2967 	host->irq = ec->irq;
2968 	ashost->host = host;
2969 	ashost->scsi.irq = host->irq;
2970 
2971 	ec->irqaddr	= ashost->fast + INT_REG;
2972 	ec->irqmask	= 0x0a;
2973 
2974 	ret = request_irq(host->irq, acornscsi_intr, 0, "acornscsi", ashost);
2975 	if (ret) {
2976 		printk(KERN_CRIT "scsi%d: IRQ%d not free: %d\n",
2977 			host->host_no, ashost->scsi.irq, ret);
2978 		goto out_put;
2979 	}
2980 
2981 	memset(&ashost->stats, 0, sizeof (ashost->stats));
2982 	queue_initialise(&ashost->queues.issue);
2983 	queue_initialise(&ashost->queues.disconnected);
2984 	msgqueue_initialise(&ashost->scsi.msgs);
2985 
2986 	acornscsi_resetcard(ashost);
2987 
2988 	ret = scsi_add_host(host, &ec->dev);
2989 	if (ret)
2990 		goto out_irq;
2991 
2992 	scsi_scan_host(host);
2993 	goto out;
2994 
2995  out_irq:
2996 	free_irq(host->irq, ashost);
2997 	msgqueue_free(&ashost->scsi.msgs);
2998 	queue_free(&ashost->queues.disconnected);
2999 	queue_free(&ashost->queues.issue);
3000  out_put:
3001 	ecardm_iounmap(ec, ashost->fast);
3002 	ecardm_iounmap(ec, ashost->base);
3003 	scsi_host_put(host);
3004  out_release:
3005 	ecard_release_resources(ec);
3006  out:
3007 	return ret;
3008 }
3009 
3010 static void acornscsi_remove(struct expansion_card *ec)
3011 {
3012 	struct Scsi_Host *host = ecard_get_drvdata(ec);
3013 	AS_Host *ashost = (AS_Host *)host->hostdata;
3014 
3015 	ecard_set_drvdata(ec, NULL);
3016 	scsi_remove_host(host);
3017 
3018 	/*
3019 	 * Put card into RESET state
3020 	 */
3021 	writeb(0x80, ashost->fast + PAGE_REG);
3022 
3023 	free_irq(host->irq, ashost);
3024 
3025 	msgqueue_free(&ashost->scsi.msgs);
3026 	queue_free(&ashost->queues.disconnected);
3027 	queue_free(&ashost->queues.issue);
3028 	ecardm_iounmap(ec, ashost->fast);
3029 	ecardm_iounmap(ec, ashost->base);
3030 	scsi_host_put(host);
3031 	ecard_release_resources(ec);
3032 }
3033 
3034 static const struct ecard_id acornscsi_cids[] = {
3035 	{ MANU_ACORN, PROD_ACORN_SCSI },
3036 	{ 0xffff, 0xffff },
3037 };
3038 
3039 static struct ecard_driver acornscsi_driver = {
3040 	.probe		= acornscsi_probe,
3041 	.remove		= acornscsi_remove,
3042 	.id_table	= acornscsi_cids,
3043 	.drv = {
3044 		.name		= "acornscsi",
3045 	},
3046 };
3047 
3048 static int __init acornscsi_init(void)
3049 {
3050 	return ecard_register_driver(&acornscsi_driver);
3051 }
3052 
3053 static void __exit acornscsi_exit(void)
3054 {
3055 	ecard_remove_driver(&acornscsi_driver);
3056 }
3057 
3058 module_init(acornscsi_init);
3059 module_exit(acornscsi_exit);
3060 
3061 MODULE_AUTHOR("Russell King");
3062 MODULE_DESCRIPTION("AcornSCSI driver");
3063 MODULE_LICENSE("GPL");
3064