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