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