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