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