Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  *  linux/drivers/acorn/scsi/acornscsi.c
0004  *
0005  *  Acorn SCSI 3 driver
0006  *  By R.M.King.
0007  *
0008  * Abandoned using the Select and Transfer command since there were
0009  * some nasty races between our software and the target devices that
0010  * were not easy to solve, and the device errata had a lot of entries
0011  * for this command, some of them quite nasty...
0012  *
0013  * Changelog:
0014  *  26-Sep-1997 RMK Re-jigged to use the queue module.
0015  *          Re-coded state machine to be based on driver
0016  *          state not scsi state.  Should be easier to debug.
0017  *          Added acornscsi_release to clean up properly.
0018  *          Updated proc/scsi reporting.
0019  *  05-Oct-1997 RMK Implemented writing to SCSI devices.
0020  *  06-Oct-1997 RMK Corrected small (non-serious) bug with the connect/
0021  *          reconnect race condition causing a warning message.
0022  *  12-Oct-1997 RMK Added catch for re-entering interrupt routine.
0023  *  15-Oct-1997 RMK Improved handling of commands.
0024  *  27-Jun-1998 RMK Changed asm/delay.h to linux/delay.h.
0025  *  13-Dec-1998 RMK Better abort code and command handling.  Extra state
0026  *          transitions added to allow dodgy devices to work.
0027  */
0028 #define DEBUG_NO_WRITE  1
0029 #define DEBUG_QUEUES    2
0030 #define DEBUG_DMA   4
0031 #define DEBUG_ABORT 8
0032 #define DEBUG_DISCON    16
0033 #define DEBUG_CONNECT   32
0034 #define DEBUG_PHASES    64
0035 #define DEBUG_WRITE 128
0036 #define DEBUG_LINK  256
0037 #define DEBUG_MESSAGES  512
0038 #define DEBUG_RESET 1024
0039 #define DEBUG_ALL   (DEBUG_RESET|DEBUG_MESSAGES|DEBUG_LINK|DEBUG_WRITE|\
0040              DEBUG_PHASES|DEBUG_CONNECT|DEBUG_DISCON|DEBUG_ABORT|\
0041              DEBUG_DMA|DEBUG_QUEUES)
0042 
0043 /* DRIVER CONFIGURATION
0044  *
0045  * SCSI-II Tagged queue support.
0046  *
0047  * I don't have any SCSI devices that support it, so it is totally untested
0048  * (except to make sure that it doesn't interfere with any non-tagging
0049  * devices).  It is not fully implemented either - what happens when a
0050  * tagging device reconnects???
0051  *
0052  * You can tell if you have a device that supports tagged queueing my
0053  * cating (eg) /proc/scsi/acornscsi/0 and see if the SCSI revision is reported
0054  * as '2 TAG'.
0055  */
0056 
0057 /*
0058  * SCSI-II Synchronous transfer support.
0059  *
0060  * Tried and tested...
0061  *
0062  * SDTR_SIZE      - maximum number of un-acknowledged bytes (0 = off, 12 = max)
0063  * SDTR_PERIOD    - period of REQ signal (min=125, max=1020)
0064  * DEFAULT_PERIOD - default REQ period.
0065  */
0066 #define SDTR_SIZE   12
0067 #define SDTR_PERIOD 125
0068 #define DEFAULT_PERIOD  500
0069 
0070 /*
0071  * Debugging information
0072  *
0073  * DEBUG      - bit mask from list above
0074  * DEBUG_TARGET   - is defined to the target number if you want to debug
0075  *          a specific target. [only recon/write/dma].
0076  */
0077 #define DEBUG (DEBUG_RESET|DEBUG_WRITE|DEBUG_NO_WRITE)
0078 /* only allow writing to SCSI device 0 */
0079 #define NO_WRITE 0xFE
0080 /*#define DEBUG_TARGET 2*/
0081 /*
0082  * Select timeout time (in 10ms units)
0083  *
0084  * This is the timeout used between the start of selection and the WD33C93
0085  * chip deciding that the device isn't responding.
0086  */
0087 #define TIMEOUT_TIME 10
0088 /*
0089  * Define this if you want to have verbose explanation of SCSI
0090  * status/messages.
0091  */
0092 #undef CONFIG_ACORNSCSI_CONSTANTS
0093 /*
0094  * Define this if you want to use the on board DMAC [don't remove this option]
0095  * If not set, then use PIO mode (not currently supported).
0096  */
0097 #define USE_DMAC
0098 
0099 /*
0100  * ====================================================================================
0101  */
0102 
0103 #ifdef DEBUG_TARGET
0104 #define DBG(cmd,xxx...) \
0105   if (cmd->device->id == DEBUG_TARGET) { \
0106     xxx; \
0107   }
0108 #else
0109 #define DBG(cmd,xxx...) xxx
0110 #endif
0111 
0112 #include <linux/module.h>
0113 #include <linux/kernel.h>
0114 #include <linux/string.h>
0115 #include <linux/signal.h>
0116 #include <linux/errno.h>
0117 #include <linux/proc_fs.h>
0118 #include <linux/ioport.h>
0119 #include <linux/blkdev.h>
0120 #include <linux/delay.h>
0121 #include <linux/interrupt.h>
0122 #include <linux/init.h>
0123 #include <linux/bitops.h>
0124 #include <linux/stringify.h>
0125 #include <linux/io.h>
0126 
0127 #include <asm/ecard.h>
0128 
0129 #include <scsi/scsi.h>
0130 #include <scsi/scsi_cmnd.h>
0131 #include <scsi/scsi_dbg.h>
0132 #include <scsi/scsi_device.h>
0133 #include <scsi/scsi_eh.h>
0134 #include <scsi/scsi_host.h>
0135 #include <scsi/scsi_tcq.h>
0136 #include <scsi/scsi_transport_spi.h>
0137 #include "acornscsi.h"
0138 #include "msgqueue.h"
0139 #include "arm_scsi.h"
0140 
0141 #include <scsi/scsicam.h>
0142 
0143 #define VER_MAJOR 2
0144 #define VER_MINOR 0
0145 #define VER_PATCH 6
0146 
0147 #ifdef USE_DMAC
0148 /*
0149  * DMAC setup parameters
0150  */ 
0151 #define INIT_DEVCON0    (DEVCON0_RQL|DEVCON0_EXW|DEVCON0_CMP)
0152 #define INIT_DEVCON1    (DEVCON1_BHLD)
0153 #define DMAC_READ   (MODECON_READ)
0154 #define DMAC_WRITE  (MODECON_WRITE)
0155 #define INIT_SBICDMA    (CTRL_DMABURST)
0156 
0157 #define scsi_xferred    have_data_in
0158 
0159 /*
0160  * Size of on-board DMA buffer
0161  */
0162 #define DMAC_BUFFER_SIZE    65536
0163 #endif
0164 
0165 #define STATUS_BUFFER_TO_PRINT  24
0166 
0167 unsigned int sdtr_period = SDTR_PERIOD;
0168 unsigned int sdtr_size   = SDTR_SIZE;
0169 
0170 static void acornscsi_done(AS_Host *host, struct scsi_cmnd **SCpntp,
0171                unsigned int result);
0172 static int acornscsi_reconnect_finish(AS_Host *host);
0173 static void acornscsi_dma_cleanup(AS_Host *host);
0174 static void acornscsi_abortcmd(AS_Host *host);
0175 
0176 /* ====================================================================================
0177  * Miscellaneous
0178  */
0179 
0180 /* Offsets from MEMC base */
0181 #define SBIC_REGIDX 0x2000
0182 #define SBIC_REGVAL 0x2004
0183 #define DMAC_OFFSET 0x3000
0184 
0185 /* Offsets from FAST IOC base */
0186 #define INT_REG     0x2000
0187 #define PAGE_REG    0x3000
0188 
0189 static inline void sbic_arm_write(AS_Host *host, unsigned int reg, unsigned int value)
0190 {
0191     writeb(reg, host->base + SBIC_REGIDX);
0192     writeb(value, host->base + SBIC_REGVAL);
0193 }
0194 
0195 static inline int sbic_arm_read(AS_Host *host, unsigned int reg)
0196 {
0197     if(reg == SBIC_ASR)
0198        return readl(host->base + SBIC_REGIDX) & 255;
0199     writeb(reg, host->base + SBIC_REGIDX);
0200     return readl(host->base + SBIC_REGVAL) & 255;
0201 }
0202 
0203 #define sbic_arm_writenext(host, val)   writeb((val), (host)->base + SBIC_REGVAL)
0204 #define sbic_arm_readnext(host)     readb((host)->base + SBIC_REGVAL)
0205 
0206 #ifdef USE_DMAC
0207 #define dmac_read(host,reg) \
0208     readb((host)->base + DMAC_OFFSET + ((reg) << 2))
0209 
0210 #define dmac_write(host,reg,value) \
0211     ({ writeb((value), (host)->base + DMAC_OFFSET + ((reg) << 2)); })
0212 
0213 #define dmac_clearintr(host)    writeb(0, (host)->fast + INT_REG)
0214 
0215 static inline unsigned int dmac_address(AS_Host *host)
0216 {
0217     return dmac_read(host, DMAC_TXADRHI) << 16 |
0218        dmac_read(host, DMAC_TXADRMD) << 8 |
0219        dmac_read(host, DMAC_TXADRLO);
0220 }
0221 
0222 static
0223 void acornscsi_dumpdma(AS_Host *host, char *where)
0224 {
0225     unsigned int mode, addr, len;
0226 
0227     mode = dmac_read(host, DMAC_MODECON);
0228     addr = dmac_address(host);
0229     len  = dmac_read(host, DMAC_TXCNTHI) << 8 |
0230            dmac_read(host, DMAC_TXCNTLO);
0231 
0232     printk("scsi%d: %s: DMAC %02x @%06x+%04x msk %02x, ",
0233         host->host->host_no, where,
0234         mode, addr, (len + 1) & 0xffff,
0235         dmac_read(host, DMAC_MASKREG));
0236 
0237     printk("DMA @%06x, ", host->dma.start_addr);
0238     printk("BH @%p +%04x, ", host->scsi.SCp.ptr,
0239         host->scsi.SCp.this_residual);
0240     printk("DT @+%04x ST @+%04x", host->dma.transferred,
0241         host->scsi.SCp.scsi_xferred);
0242     printk("\n");
0243 }
0244 #endif
0245 
0246 static
0247 unsigned long acornscsi_sbic_xfcount(AS_Host *host)
0248 {
0249     unsigned long length;
0250 
0251     length = sbic_arm_read(host, SBIC_TRANSCNTH) << 16;
0252     length |= sbic_arm_readnext(host) << 8;
0253     length |= sbic_arm_readnext(host);
0254 
0255     return length;
0256 }
0257 
0258 static int
0259 acornscsi_sbic_wait(AS_Host *host, int stat_mask, int stat, int timeout, char *msg)
0260 {
0261     int asr;
0262 
0263     do {
0264         asr = sbic_arm_read(host, SBIC_ASR);
0265 
0266         if ((asr & stat_mask) == stat)
0267             return 0;
0268 
0269         udelay(1);
0270     } while (--timeout);
0271 
0272     printk("scsi%d: timeout while %s\n", host->host->host_no, msg);
0273 
0274     return -1;
0275 }
0276 
0277 static
0278 int acornscsi_sbic_issuecmd(AS_Host *host, int command)
0279 {
0280     if (acornscsi_sbic_wait(host, ASR_CIP, 0, 1000, "issuing command"))
0281     return -1;
0282 
0283     sbic_arm_write(host, SBIC_CMND, command);
0284 
0285     return 0;
0286 }
0287 
0288 static void
0289 acornscsi_csdelay(unsigned int cs)
0290 {
0291     unsigned long target_jiffies, flags;
0292 
0293     target_jiffies = jiffies + 1 + cs * HZ / 100;
0294 
0295     local_save_flags(flags);
0296     local_irq_enable();
0297 
0298     while (time_before(jiffies, target_jiffies)) barrier();
0299 
0300     local_irq_restore(flags);
0301 }
0302 
0303 static
0304 void acornscsi_resetcard(AS_Host *host)
0305 {
0306     unsigned int i, timeout;
0307 
0308     /* assert reset line */
0309     host->card.page_reg = 0x80;
0310     writeb(host->card.page_reg, host->fast + PAGE_REG);
0311 
0312     /* wait 3 cs.  SCSI standard says 25ms. */
0313     acornscsi_csdelay(3);
0314 
0315     host->card.page_reg = 0;
0316     writeb(host->card.page_reg, host->fast + PAGE_REG);
0317 
0318     /*
0319      * Should get a reset from the card
0320      */
0321     timeout = 1000;
0322     do {
0323     if (readb(host->fast + INT_REG) & 8)
0324         break;
0325     udelay(1);
0326     } while (--timeout);
0327 
0328     if (timeout == 0)
0329     printk("scsi%d: timeout while resetting card\n",
0330         host->host->host_no);
0331 
0332     sbic_arm_read(host, SBIC_ASR);
0333     sbic_arm_read(host, SBIC_SSR);
0334 
0335     /* setup sbic - WD33C93A */
0336     sbic_arm_write(host, SBIC_OWNID, OWNID_EAF | host->host->this_id);
0337     sbic_arm_write(host, SBIC_CMND, CMND_RESET);
0338 
0339     /*
0340      * Command should cause a reset interrupt
0341      */
0342     timeout = 1000;
0343     do {
0344     if (readb(host->fast + INT_REG) & 8)
0345         break;
0346     udelay(1);
0347     } while (--timeout);
0348 
0349     if (timeout == 0)
0350     printk("scsi%d: timeout while resetting card\n",
0351         host->host->host_no);
0352 
0353     sbic_arm_read(host, SBIC_ASR);
0354     if (sbic_arm_read(host, SBIC_SSR) != 0x01)
0355     printk(KERN_CRIT "scsi%d: WD33C93A didn't give enhanced reset interrupt\n",
0356         host->host->host_no);
0357 
0358     sbic_arm_write(host, SBIC_CTRL, INIT_SBICDMA | CTRL_IDI);
0359     sbic_arm_write(host, SBIC_TIMEOUT, TIMEOUT_TIME);
0360     sbic_arm_write(host, SBIC_SYNCHTRANSFER, SYNCHTRANSFER_2DBA);
0361     sbic_arm_write(host, SBIC_SOURCEID, SOURCEID_ER | SOURCEID_DSP);
0362 
0363     host->card.page_reg = 0x40;
0364     writeb(host->card.page_reg, host->fast + PAGE_REG);
0365 
0366     /* setup dmac - uPC71071 */
0367     dmac_write(host, DMAC_INIT, 0);
0368 #ifdef USE_DMAC
0369     dmac_write(host, DMAC_INIT, INIT_8BIT);
0370     dmac_write(host, DMAC_CHANNEL, CHANNEL_0);
0371     dmac_write(host, DMAC_DEVCON0, INIT_DEVCON0);
0372     dmac_write(host, DMAC_DEVCON1, INIT_DEVCON1);
0373 #endif
0374 
0375     host->SCpnt = NULL;
0376     host->scsi.phase = PHASE_IDLE;
0377     host->scsi.disconnectable = 0;
0378 
0379     memset(host->busyluns, 0, sizeof(host->busyluns));
0380 
0381     for (i = 0; i < 8; i++) {
0382     host->device[i].sync_state = SYNC_NEGOCIATE;
0383     host->device[i].disconnect_ok = 1;
0384     }
0385 
0386     /* wait 25 cs.  SCSI standard says 250ms. */
0387     acornscsi_csdelay(25);
0388 }
0389 
0390 /*=============================================================================================
0391  * Utility routines (eg. debug)
0392  */
0393 #ifdef CONFIG_ACORNSCSI_CONSTANTS
0394 static char *acornscsi_interrupttype[] = {
0395   "rst",  "suc",  "p/a",  "3",
0396   "term", "5",    "6",    "7",
0397   "serv", "9",    "a",    "b",
0398   "c",    "d",    "e",    "f"
0399 };
0400 
0401 static signed char acornscsi_map[] = {
0402   0,  1, -1, -1,  -1, -1, -1, -1,  -1, -1, -1, -1,  -1, -1, -1, -1,
0403  -1,  2, -1, -1,  -1, -1,  3, -1,   4,  5,  6,  7,   8,  9, 10, 11,
0404  12, 13, 14, -1,  -1, -1, -1, -1,   4,  5,  6,  7,   8,  9, 10, 11,
0405  -1, -1, -1, -1,  -1, -1, -1, -1,  -1, -1, -1, -1,  -1, -1, -1, -1,
0406  15, 16, 17, 18,  19, -1, -1, 20,   4,  5,  6,  7,   8,  9, 10, 11,
0407  -1, -1, -1, -1,  -1, -1, -1, -1,  -1, -1, -1, -1,  -1, -1, -1, -1,
0408  -1, -1, -1, -1,  -1, -1, -1, -1,  -1, -1, -1, -1,  -1, -1, -1, -1,
0409  -1, -1, -1, -1,  -1, -1, -1, -1,  -1, -1, -1, -1,  -1, -1, -1, -1,
0410  21, 22, -1, -1,  -1, 23, -1, -1,   4,  5,  6,  7,   8,  9, 10, 11,
0411  -1, -1, -1, -1,  -1, -1, -1, -1,  -1, -1, -1, -1,  -1, -1, -1, -1,
0412  -1, -1, -1, -1,  -1, -1, -1, -1,  -1, -1, -1, -1,  -1, -1, -1, -1,
0413  -1, -1, -1, -1,  -1, -1, -1, -1,  -1, -1, -1, -1,  -1, -1, -1, -1,
0414  -1, -1, -1, -1,  -1, -1, -1, -1,  -1, -1, -1, -1,  -1, -1, -1, -1,
0415  -1, -1, -1, -1,  -1, -1, -1, -1,  -1, -1, -1, -1,  -1, -1, -1, -1,
0416  -1, -1, -1, -1,  -1, -1, -1, -1,  -1, -1, -1, -1,  -1, -1, -1, -1,
0417  -1, -1, -1, -1,  -1, -1, -1, -1,  -1, -1, -1, -1,  -1, -1, -1, -1
0418 };      
0419 
0420 static char *acornscsi_interruptcode[] = {
0421     /* 0 */
0422     "reset - normal mode",  /* 00 */
0423     "reset - advanced mode",    /* 01 */
0424 
0425     /* 2 */
0426     "sel",          /* 11 */
0427     "sel+xfer",         /* 16 */
0428     "data-out",         /* 18 */
0429     "data-in",          /* 19 */
0430     "cmd",          /* 1A */
0431     "stat",         /* 1B */
0432     "??-out",           /* 1C */
0433     "??-in",            /* 1D */
0434     "msg-out",          /* 1E */
0435     "msg-in",           /* 1F */
0436 
0437     /* 12 */
0438     "/ACK asserted",        /* 20 */
0439     "save-data-ptr",        /* 21 */
0440     "{re}sel",          /* 22 */
0441 
0442     /* 15 */
0443     "inv cmd",          /* 40 */
0444     "unexpected disconnect",    /* 41 */
0445     "sel timeout",      /* 42 */
0446     "P err",            /* 43 */
0447     "P err+ATN",        /* 44 */
0448     "bad status byte",      /* 47 */
0449 
0450     /* 21 */
0451     "resel, no id",     /* 80 */
0452     "resel",            /* 81 */
0453     "discon",           /* 85 */
0454 };
0455 
0456 static
0457 void print_scsi_status(unsigned int ssr)
0458 {
0459     if (acornscsi_map[ssr] != -1)
0460     printk("%s:%s",
0461         acornscsi_interrupttype[(ssr >> 4)],
0462         acornscsi_interruptcode[acornscsi_map[ssr]]);
0463     else
0464     printk("%X:%X", ssr >> 4, ssr & 0x0f);    
0465 }    
0466 #endif
0467 
0468 static
0469 void print_sbic_status(int asr, int ssr, int cmdphase)
0470 {
0471 #ifdef CONFIG_ACORNSCSI_CONSTANTS
0472     printk("sbic: %c%c%c%c%c%c ",
0473         asr & ASR_INT ? 'I' : 'i',
0474         asr & ASR_LCI ? 'L' : 'l',
0475         asr & ASR_BSY ? 'B' : 'b',
0476         asr & ASR_CIP ? 'C' : 'c',
0477         asr & ASR_PE  ? 'P' : 'p',
0478         asr & ASR_DBR ? 'D' : 'd');
0479     printk("scsi: ");
0480     print_scsi_status(ssr);
0481     printk(" ph %02X\n", cmdphase);
0482 #else
0483     printk("sbic: %02X scsi: %X:%X ph: %02X\n",
0484         asr, (ssr & 0xf0)>>4, ssr & 0x0f, cmdphase);
0485 #endif
0486 }
0487 
0488 static void
0489 acornscsi_dumplogline(AS_Host *host, int target, int line)
0490 {
0491     unsigned long prev;
0492     signed int ptr;
0493 
0494     ptr = host->status_ptr[target] - STATUS_BUFFER_TO_PRINT;
0495     if (ptr < 0)
0496         ptr += STATUS_BUFFER_SIZE;
0497 
0498     printk("%c: %3s:", target == 8 ? 'H' : '0' + target,
0499         line == 0 ? "ph" : line == 1 ? "ssr" : "int");
0500 
0501     prev = host->status[target][ptr].when;
0502 
0503     for (; ptr != host->status_ptr[target]; ptr = (ptr + 1) & (STATUS_BUFFER_SIZE - 1)) {
0504         unsigned long time_diff;
0505 
0506         if (!host->status[target][ptr].when)
0507             continue;
0508 
0509         switch (line) {
0510         case 0:
0511             printk("%c%02X", host->status[target][ptr].irq ? '-' : ' ',
0512                      host->status[target][ptr].ph);
0513             break;
0514 
0515         case 1:
0516             printk(" %02X", host->status[target][ptr].ssr);
0517             break;
0518 
0519         case 2:
0520             time_diff = host->status[target][ptr].when - prev;
0521             prev = host->status[target][ptr].when;
0522             if (time_diff == 0)
0523                 printk("==^");
0524             else if (time_diff >= 100)
0525                 printk("   ");
0526             else
0527                 printk(" %02ld", time_diff);
0528             break;
0529         }
0530     }
0531 
0532     printk("\n");
0533 }
0534 
0535 static
0536 void acornscsi_dumplog(AS_Host *host, int target)
0537 {
0538     do {
0539     acornscsi_dumplogline(host, target, 0);
0540     acornscsi_dumplogline(host, target, 1);
0541     acornscsi_dumplogline(host, target, 2);
0542 
0543     if (target == 8)
0544         break;
0545 
0546     target = 8;
0547     } while (1);
0548 }
0549 
0550 static
0551 char acornscsi_target(AS_Host *host)
0552 {
0553     if (host->SCpnt)
0554         return '0' + host->SCpnt->device->id;
0555     return 'H';
0556 }
0557 
0558 /*
0559  * Prototype: cmdtype_t acornscsi_cmdtype(int command)
0560  * Purpose  : differentiate READ from WRITE from other commands
0561  * Params   : command - command to interpret
0562  * Returns  : CMD_READ  - command reads data,
0563  *        CMD_WRITE - command writes data,
0564  *        CMD_MISC  - everything else
0565  */
0566 static inline
0567 cmdtype_t acornscsi_cmdtype(int command)
0568 {
0569     switch (command) {
0570     case WRITE_6:  case WRITE_10:  case WRITE_12:
0571     return CMD_WRITE;
0572     case READ_6:   case READ_10:   case READ_12:
0573     return CMD_READ;
0574     default:
0575     return CMD_MISC;
0576     }
0577 }
0578 
0579 /*
0580  * Prototype: int acornscsi_datadirection(int command)
0581  * Purpose  : differentiate between commands that have a DATA IN phase
0582  *        and a DATA OUT phase
0583  * Params   : command - command to interpret
0584  * Returns  : DATADIR_OUT - data out phase expected
0585  *        DATADIR_IN  - data in phase expected
0586  */
0587 static
0588 datadir_t acornscsi_datadirection(int command)
0589 {
0590     switch (command) {
0591     case CHANGE_DEFINITION: case COMPARE:       case COPY:
0592     case COPY_VERIFY:       case LOG_SELECT:    case MODE_SELECT:
0593     case MODE_SELECT_10:    case SEND_DIAGNOSTIC:   case WRITE_BUFFER:
0594     case FORMAT_UNIT:       case REASSIGN_BLOCKS:   case RESERVE:
0595     case SEARCH_EQUAL:      case SEARCH_HIGH:   case SEARCH_LOW:
0596     case WRITE_6:       case WRITE_10:      case WRITE_VERIFY:
0597     case UPDATE_BLOCK:      case WRITE_LONG:    case WRITE_SAME:
0598     case SEARCH_HIGH_12:    case SEARCH_EQUAL_12:   case SEARCH_LOW_12:
0599     case WRITE_12:      case WRITE_VERIFY_12:   case SET_WINDOW:
0600     case MEDIUM_SCAN:       case SEND_VOLUME_TAG:   case 0xea:
0601     return DATADIR_OUT;
0602     default:
0603     return DATADIR_IN;
0604     }
0605 }
0606 
0607 /*
0608  * Purpose  : provide values for synchronous transfers with 33C93.
0609  * Copyright: Copyright (c) 1996 John Shifflett, GeoLog Consulting
0610  *  Modified by Russell King for 8MHz WD33C93A
0611  */
0612 static struct sync_xfer_tbl {
0613     unsigned int period_ns;
0614     unsigned char reg_value;
0615 } sync_xfer_table[] = {
0616     {   1, 0x20 },    { 249, 0x20 },    { 374, 0x30 },
0617     { 499, 0x40 },    { 624, 0x50 },    { 749, 0x60 },
0618     { 874, 0x70 },    { 999, 0x00 },    {   0,    0 }
0619 };
0620 
0621 /*
0622  * Prototype: int acornscsi_getperiod(unsigned char syncxfer)
0623  * Purpose  : period for the synchronous transfer setting
0624  * Params   : syncxfer SYNCXFER register value
0625  * Returns  : period in ns.
0626  */
0627 static
0628 int acornscsi_getperiod(unsigned char syncxfer)
0629 {
0630     int i;
0631 
0632     syncxfer &= 0xf0;
0633     if (syncxfer == 0x10)
0634     syncxfer = 0;
0635 
0636     for (i = 1; sync_xfer_table[i].period_ns; i++)
0637     if (syncxfer == sync_xfer_table[i].reg_value)
0638         return sync_xfer_table[i].period_ns;
0639     return 0;
0640 }
0641 
0642 /*
0643  * Prototype: int round_period(unsigned int period)
0644  * Purpose  : return index into above table for a required REQ period
0645  * Params   : period - time (ns) for REQ
0646  * Returns  : table index
0647  * Copyright: Copyright (c) 1996 John Shifflett, GeoLog Consulting
0648  */
0649 static inline
0650 int round_period(unsigned int period)
0651 {
0652     int i;
0653 
0654     for (i = 1; sync_xfer_table[i].period_ns; i++) {
0655     if ((period <= sync_xfer_table[i].period_ns) &&
0656         (period > sync_xfer_table[i - 1].period_ns))
0657         return i;
0658     }
0659     return 7;
0660 }
0661 
0662 /*
0663  * Prototype: unsigned char calc_sync_xfer(unsigned int period, unsigned int offset)
0664  * Purpose  : calculate value for 33c93s SYNC register
0665  * Params   : period - time (ns) for REQ
0666  *        offset - offset in bytes between REQ/ACK
0667  * Returns  : value for SYNC register
0668  * Copyright: Copyright (c) 1996 John Shifflett, GeoLog Consulting
0669  */
0670 static
0671 unsigned char __maybe_unused calc_sync_xfer(unsigned int period,
0672                         unsigned int offset)
0673 {
0674     return sync_xfer_table[round_period(period)].reg_value |
0675         ((offset < SDTR_SIZE) ? offset : SDTR_SIZE);
0676 }
0677 
0678 /* ====================================================================================
0679  * Command functions
0680  */
0681 /*
0682  * Function: acornscsi_kick(AS_Host *host)
0683  * Purpose : kick next command to interface
0684  * Params  : host - host to send command to
0685  * Returns : INTR_IDLE if idle, otherwise INTR_PROCESSING
0686  * Notes   : interrupts are always disabled!
0687  */
0688 static
0689 intr_ret_t acornscsi_kick(AS_Host *host)
0690 {
0691     int from_queue = 0;
0692     struct scsi_cmnd *SCpnt;
0693 
0694     /* first check to see if a command is waiting to be executed */
0695     SCpnt = host->origSCpnt;
0696     host->origSCpnt = NULL;
0697 
0698     /* retrieve next command */
0699     if (!SCpnt) {
0700     SCpnt = queue_remove_exclude(&host->queues.issue, host->busyluns);
0701     if (!SCpnt)
0702         return INTR_IDLE;
0703 
0704     from_queue = 1;
0705     }
0706 
0707     if (host->scsi.disconnectable && host->SCpnt) {
0708     queue_add_cmd_tail(&host->queues.disconnected, host->SCpnt);
0709     host->scsi.disconnectable = 0;
0710 #if (DEBUG & (DEBUG_QUEUES|DEBUG_DISCON))
0711     DBG(host->SCpnt, printk("scsi%d.%c: moved command to disconnected queue\n",
0712         host->host->host_no, acornscsi_target(host)));
0713 #endif
0714     host->SCpnt = NULL;
0715     }
0716 
0717     /*
0718      * If we have an interrupt pending, then we may have been reselected.
0719      * In this case, we don't want to write to the registers
0720      */
0721     if (!(sbic_arm_read(host, SBIC_ASR) & (ASR_INT|ASR_BSY|ASR_CIP))) {
0722     sbic_arm_write(host, SBIC_DESTID, SCpnt->device->id);
0723     sbic_arm_write(host, SBIC_CMND, CMND_SELWITHATN);
0724     }
0725 
0726     /*
0727      * claim host busy - all of these must happen atomically wrt
0728      * our interrupt routine.  Failure means command loss.
0729      */
0730     host->scsi.phase = PHASE_CONNECTING;
0731     host->SCpnt = SCpnt;
0732     host->scsi.SCp = *arm_scsi_pointer(SCpnt);
0733     host->dma.xfer_setup = 0;
0734     host->dma.xfer_required = 0;
0735     host->dma.xfer_done = 0;
0736 
0737 #if (DEBUG & (DEBUG_ABORT|DEBUG_CONNECT))
0738     DBG(SCpnt,printk("scsi%d.%c: starting cmd %02X\n",
0739         host->host->host_no, '0' + SCpnt->device->id,
0740         SCpnt->cmnd[0]));
0741 #endif
0742 
0743     if (from_queue) {
0744         set_bit(SCpnt->device->id * 8 +
0745             (u8)(SCpnt->device->lun & 0x07), host->busyluns);
0746 
0747     host->stats.removes += 1;
0748 
0749     switch (acornscsi_cmdtype(SCpnt->cmnd[0])) {
0750     case CMD_WRITE:
0751         host->stats.writes += 1;
0752         break;
0753     case CMD_READ:
0754         host->stats.reads += 1;
0755         break;
0756     case CMD_MISC:
0757         host->stats.miscs += 1;
0758         break;
0759     }
0760     }
0761 
0762     return INTR_PROCESSING;
0763 }    
0764 
0765 /*
0766  * Function: void acornscsi_done(AS_Host *host, struct scsi_cmnd **SCpntp, unsigned int result)
0767  * Purpose : complete processing for command
0768  * Params  : host   - interface that completed
0769  *       result - driver byte of result
0770  */
0771 static void acornscsi_done(AS_Host *host, struct scsi_cmnd **SCpntp,
0772                unsigned int result)
0773 {
0774     struct scsi_cmnd *SCpnt = *SCpntp;
0775 
0776     /* clean up */
0777     sbic_arm_write(host, SBIC_SOURCEID, SOURCEID_ER | SOURCEID_DSP);
0778 
0779     host->stats.fins += 1;
0780 
0781     if (SCpnt) {
0782     *SCpntp = NULL;
0783 
0784     acornscsi_dma_cleanup(host);
0785 
0786     set_host_byte(SCpnt, result);
0787     if (result == DID_OK)
0788         scsi_msg_to_host_byte(SCpnt, host->scsi.SCp.Message);
0789     set_status_byte(SCpnt, host->scsi.SCp.Status);
0790 
0791     /*
0792      * In theory, this should not happen.  In practice, it seems to.
0793      * Only trigger an error if the device attempts to report all happy
0794      * but with untransferred buffers...  If we don't do something, then
0795      * data loss will occur.  Should we check SCpnt->underflow here?
0796      * It doesn't appear to be set to something meaningful by the higher
0797      * levels all the time.
0798      */
0799     if (result == DID_OK) {
0800         int xfer_warn = 0;
0801 
0802         if (SCpnt->underflow == 0) {
0803             if (host->scsi.SCp.ptr &&
0804                 acornscsi_cmdtype(SCpnt->cmnd[0]) != CMD_MISC)
0805                 xfer_warn = 1;
0806         } else {
0807             if (host->scsi.SCp.scsi_xferred < SCpnt->underflow ||
0808                 host->scsi.SCp.scsi_xferred != host->dma.transferred)
0809                 xfer_warn = 1;
0810         }
0811 
0812         /* ANSI standard says: (SCSI-2 Rev 10c Sect 5.6.6)
0813          *  Targets which break data transfers into multiple
0814          *  connections shall end each successful connection
0815          *  (except possibly the last) with a SAVE DATA
0816          *  POINTER - DISCONNECT message sequence.
0817          *
0818          * This makes it difficult to ensure that a transfer has
0819          * completed.  If we reach the end of a transfer during
0820          * the command, then we can only have finished the transfer.
0821          * therefore, if we seem to have some data remaining, this
0822          * is not a problem.
0823          */
0824         if (host->dma.xfer_done)
0825             xfer_warn = 0;
0826 
0827         if (xfer_warn) {
0828             switch (get_status_byte(SCpnt)) {
0829             case SAM_STAT_CHECK_CONDITION:
0830             case SAM_STAT_COMMAND_TERMINATED:
0831             case SAM_STAT_BUSY:
0832             case SAM_STAT_TASK_SET_FULL:
0833             case SAM_STAT_RESERVATION_CONFLICT:
0834             break;
0835 
0836             default:
0837             scmd_printk(KERN_ERR, SCpnt,
0838                     "incomplete data transfer detected: "
0839                     "result=%08X", SCpnt->result);
0840             scsi_print_command(SCpnt);
0841             acornscsi_dumpdma(host, "done");
0842             acornscsi_dumplog(host, SCpnt->device->id);
0843             set_host_byte(SCpnt, DID_ERROR);
0844             }
0845         }
0846     }
0847 
0848     clear_bit(SCpnt->device->id * 8 +
0849           (u8)(SCpnt->device->lun & 0x7), host->busyluns);
0850 
0851     scsi_done(SCpnt);
0852     } else
0853     printk("scsi%d: null command in acornscsi_done", host->host->host_no);
0854 
0855     host->scsi.phase = PHASE_IDLE;
0856 }
0857 
0858 /* ====================================================================================
0859  * DMA routines
0860  */
0861 /*
0862  * Purpose  : update SCSI Data Pointer
0863  * Notes    : this will only be one SG entry or less
0864  */
0865 static
0866 void acornscsi_data_updateptr(AS_Host *host, struct scsi_pointer *SCp, unsigned int length)
0867 {
0868     SCp->ptr += length;
0869     SCp->this_residual -= length;
0870 
0871     if (SCp->this_residual == 0 && next_SCp(SCp) == 0)
0872     host->dma.xfer_done = 1;
0873 }
0874 
0875 /*
0876  * Prototype: void acornscsi_data_read(AS_Host *host, char *ptr,
0877  *              unsigned int start_addr, unsigned int length)
0878  * Purpose  : read data from DMA RAM
0879  * Params   : host - host to transfer from
0880  *        ptr  - DRAM address
0881  *        start_addr - host mem address
0882  *        length - number of bytes to transfer
0883  * Notes    : this will only be one SG entry or less
0884  */
0885 static
0886 void acornscsi_data_read(AS_Host *host, char *ptr,
0887                  unsigned int start_addr, unsigned int length)
0888 {
0889     extern void __acornscsi_in(void __iomem *, char *buf, int len);
0890     unsigned int page, offset, len = length;
0891 
0892     page = (start_addr >> 12);
0893     offset = start_addr & ((1 << 12) - 1);
0894 
0895     writeb((page & 0x3f) | host->card.page_reg, host->fast + PAGE_REG);
0896 
0897     while (len > 0) {
0898     unsigned int this_len;
0899 
0900     if (len + offset > (1 << 12))
0901         this_len = (1 << 12) - offset;
0902     else
0903         this_len = len;
0904 
0905     __acornscsi_in(host->base + (offset << 1), ptr, this_len);
0906 
0907     offset += this_len;
0908     ptr += this_len;
0909     len -= this_len;
0910 
0911     if (offset == (1 << 12)) {
0912         offset = 0;
0913         page ++;
0914         writeb((page & 0x3f) | host->card.page_reg, host->fast + PAGE_REG);
0915     }
0916     }
0917     writeb(host->card.page_reg, host->fast + PAGE_REG);
0918 }
0919 
0920 /*
0921  * Prototype: void acornscsi_data_write(AS_Host *host, char *ptr,
0922  *              unsigned int start_addr, unsigned int length)
0923  * Purpose  : write data to DMA RAM
0924  * Params   : host - host to transfer from
0925  *        ptr  - DRAM address
0926  *        start_addr - host mem address
0927  *        length - number of bytes to transfer
0928  * Notes    : this will only be one SG entry or less
0929  */
0930 static
0931 void acornscsi_data_write(AS_Host *host, char *ptr,
0932                  unsigned int start_addr, unsigned int length)
0933 {
0934     extern void __acornscsi_out(void __iomem *, char *buf, int len);
0935     unsigned int page, offset, len = length;
0936 
0937     page = (start_addr >> 12);
0938     offset = start_addr & ((1 << 12) - 1);
0939 
0940     writeb((page & 0x3f) | host->card.page_reg, host->fast + PAGE_REG);
0941 
0942     while (len > 0) {
0943     unsigned int this_len;
0944 
0945     if (len + offset > (1 << 12))
0946         this_len = (1 << 12) - offset;
0947     else
0948         this_len = len;
0949 
0950     __acornscsi_out(host->base + (offset << 1), ptr, this_len);
0951 
0952     offset += this_len;
0953     ptr += this_len;
0954     len -= this_len;
0955 
0956     if (offset == (1 << 12)) {
0957         offset = 0;
0958         page ++;
0959         writeb((page & 0x3f) | host->card.page_reg, host->fast + PAGE_REG);
0960     }
0961     }
0962     writeb(host->card.page_reg, host->fast + PAGE_REG);
0963 }
0964 
0965 /* =========================================================================================
0966  * On-board DMA routines
0967  */
0968 #ifdef USE_DMAC
0969 /*
0970  * Prototype: void acornscsi_dmastop(AS_Host *host)
0971  * Purpose  : stop all DMA
0972  * Params   : host - host on which to stop DMA
0973  * Notes    : This is called when leaving DATA IN/OUT phase,
0974  *        or when interface is RESET
0975  */
0976 static inline
0977 void acornscsi_dma_stop(AS_Host *host)
0978 {
0979     dmac_write(host, DMAC_MASKREG, MASK_ON);
0980     dmac_clearintr(host);
0981 
0982 #if (DEBUG & DEBUG_DMA)
0983     DBG(host->SCpnt, acornscsi_dumpdma(host, "stop"));
0984 #endif
0985 }
0986 
0987 /*
0988  * Function: void acornscsi_dma_setup(AS_Host *host, dmadir_t direction)
0989  * Purpose : setup DMA controller for data transfer
0990  * Params  : host - host to setup
0991  *       direction - data transfer direction
0992  * Notes   : This is called when entering DATA I/O phase, not
0993  *       while we're in a DATA I/O phase
0994  */
0995 static
0996 void acornscsi_dma_setup(AS_Host *host, dmadir_t direction)
0997 {
0998     unsigned int address, length, mode;
0999 
1000     host->dma.direction = direction;
1001 
1002     dmac_write(host, DMAC_MASKREG, MASK_ON);
1003 
1004     if (direction == DMA_OUT) {
1005 #if (DEBUG & DEBUG_NO_WRITE)
1006     if (NO_WRITE & (1 << host->SCpnt->device->id)) {
1007         printk(KERN_CRIT "scsi%d.%c: I can't handle DMA_OUT!\n",
1008             host->host->host_no, acornscsi_target(host));
1009         return;
1010     }
1011 #endif
1012     mode = DMAC_WRITE;
1013     } else
1014     mode = DMAC_READ;
1015 
1016     /*
1017      * Allocate some buffer space, limited to half the buffer size
1018      */
1019     length = min_t(unsigned int, host->scsi.SCp.this_residual, DMAC_BUFFER_SIZE / 2);
1020     if (length) {
1021     host->dma.start_addr = address = host->dma.free_addr;
1022     host->dma.free_addr = (host->dma.free_addr + length) &
1023                 (DMAC_BUFFER_SIZE - 1);
1024 
1025     /*
1026      * Transfer data to DMA memory
1027      */
1028     if (direction == DMA_OUT)
1029         acornscsi_data_write(host, host->scsi.SCp.ptr, host->dma.start_addr,
1030                 length);
1031 
1032     length -= 1;
1033     dmac_write(host, DMAC_TXCNTLO, length);
1034     dmac_write(host, DMAC_TXCNTHI, length >> 8);
1035     dmac_write(host, DMAC_TXADRLO, address);
1036     dmac_write(host, DMAC_TXADRMD, address >> 8);
1037     dmac_write(host, DMAC_TXADRHI, 0);
1038     dmac_write(host, DMAC_MODECON, mode);
1039     dmac_write(host, DMAC_MASKREG, MASK_OFF);
1040 
1041 #if (DEBUG & DEBUG_DMA)
1042     DBG(host->SCpnt, acornscsi_dumpdma(host, "strt"));
1043 #endif
1044     host->dma.xfer_setup = 1;
1045     }
1046 }
1047 
1048 /*
1049  * Function: void acornscsi_dma_cleanup(AS_Host *host)
1050  * Purpose : ensure that all DMA transfers are up-to-date & host->scsi.SCp is correct
1051  * Params  : host - host to finish
1052  * Notes   : This is called when a command is:
1053  *      terminating, RESTORE_POINTERS, SAVE_POINTERS, DISCONNECT
1054  *     : This must not return until all transfers are completed.
1055  */
1056 static
1057 void acornscsi_dma_cleanup(AS_Host *host)
1058 {
1059     dmac_write(host, DMAC_MASKREG, MASK_ON);
1060     dmac_clearintr(host);
1061 
1062     /*
1063      * Check for a pending transfer
1064      */
1065     if (host->dma.xfer_required) {
1066     host->dma.xfer_required = 0;
1067     if (host->dma.direction == DMA_IN)
1068         acornscsi_data_read(host, host->dma.xfer_ptr,
1069                  host->dma.xfer_start, host->dma.xfer_length);
1070     }
1071 
1072     /*
1073      * Has a transfer been setup?
1074      */
1075     if (host->dma.xfer_setup) {
1076     unsigned int transferred;
1077 
1078     host->dma.xfer_setup = 0;
1079 
1080 #if (DEBUG & DEBUG_DMA)
1081     DBG(host->SCpnt, acornscsi_dumpdma(host, "cupi"));
1082 #endif
1083 
1084     /*
1085      * Calculate number of bytes transferred from DMA.
1086      */
1087     transferred = dmac_address(host) - host->dma.start_addr;
1088     host->dma.transferred += transferred;
1089 
1090     if (host->dma.direction == DMA_IN)
1091         acornscsi_data_read(host, host->scsi.SCp.ptr,
1092                  host->dma.start_addr, transferred);
1093 
1094     /*
1095      * Update SCSI pointers
1096      */
1097     acornscsi_data_updateptr(host, &host->scsi.SCp, transferred);
1098 #if (DEBUG & DEBUG_DMA)
1099     DBG(host->SCpnt, acornscsi_dumpdma(host, "cupo"));
1100 #endif
1101     }
1102 }
1103 
1104 /*
1105  * Function: void acornscsi_dmacintr(AS_Host *host)
1106  * Purpose : handle interrupts from DMAC device
1107  * Params  : host - host to process
1108  * Notes   : If reading, we schedule the read to main memory &
1109  *       allow the transfer to continue.
1110  *     : If writing, we fill the onboard DMA memory from main
1111  *       memory.
1112  *     : Called whenever DMAC finished it's current transfer.
1113  */
1114 static
1115 void acornscsi_dma_intr(AS_Host *host)
1116 {
1117     unsigned int address, length, transferred;
1118 
1119 #if (DEBUG & DEBUG_DMA)
1120     DBG(host->SCpnt, acornscsi_dumpdma(host, "inti"));
1121 #endif
1122 
1123     dmac_write(host, DMAC_MASKREG, MASK_ON);
1124     dmac_clearintr(host);
1125 
1126     /*
1127      * Calculate amount transferred via DMA
1128      */
1129     transferred = dmac_address(host) - host->dma.start_addr;
1130     host->dma.transferred += transferred;
1131 
1132     /*
1133      * Schedule DMA transfer off board
1134      */
1135     if (host->dma.direction == DMA_IN) {
1136     host->dma.xfer_start = host->dma.start_addr;
1137     host->dma.xfer_length = transferred;
1138     host->dma.xfer_ptr = host->scsi.SCp.ptr;
1139     host->dma.xfer_required = 1;
1140     }
1141 
1142     acornscsi_data_updateptr(host, &host->scsi.SCp, transferred);
1143 
1144     /*
1145      * Allocate some buffer space, limited to half the on-board RAM size
1146      */
1147     length = min_t(unsigned int, host->scsi.SCp.this_residual, DMAC_BUFFER_SIZE / 2);
1148     if (length) {
1149     host->dma.start_addr = address = host->dma.free_addr;
1150     host->dma.free_addr = (host->dma.free_addr + length) &
1151                 (DMAC_BUFFER_SIZE - 1);
1152 
1153     /*
1154      * Transfer data to DMA memory
1155      */
1156     if (host->dma.direction == DMA_OUT)
1157         acornscsi_data_write(host, host->scsi.SCp.ptr, host->dma.start_addr,
1158                 length);
1159 
1160     length -= 1;
1161     dmac_write(host, DMAC_TXCNTLO, length);
1162     dmac_write(host, DMAC_TXCNTHI, length >> 8);
1163     dmac_write(host, DMAC_TXADRLO, address);
1164     dmac_write(host, DMAC_TXADRMD, address >> 8);
1165     dmac_write(host, DMAC_TXADRHI, 0);
1166     dmac_write(host, DMAC_MASKREG, MASK_OFF);
1167 
1168 #if (DEBUG & DEBUG_DMA)
1169     DBG(host->SCpnt, acornscsi_dumpdma(host, "into"));
1170 #endif
1171     } else {
1172     host->dma.xfer_setup = 0;
1173 #if 0
1174     /*
1175      * If the interface still wants more, then this is an error.
1176      * We give it another byte, but we also attempt to raise an
1177      * attention condition.  We continue giving one byte until
1178      * the device recognises the attention.
1179      */
1180     if (dmac_read(host, DMAC_STATUS) & STATUS_RQ0) {
1181         acornscsi_abortcmd(host);
1182 
1183         dmac_write(host, DMAC_TXCNTLO, 0);
1184         dmac_write(host, DMAC_TXCNTHI, 0);
1185         dmac_write(host, DMAC_TXADRLO, 0);
1186         dmac_write(host, DMAC_TXADRMD, 0);
1187         dmac_write(host, DMAC_TXADRHI, 0);
1188         dmac_write(host, DMAC_MASKREG, MASK_OFF);
1189     }
1190 #endif
1191     }
1192 }
1193 
1194 /*
1195  * Function: void acornscsi_dma_xfer(AS_Host *host)
1196  * Purpose : transfer data between AcornSCSI and memory
1197  * Params  : host - host to process
1198  */
1199 static
1200 void acornscsi_dma_xfer(AS_Host *host)
1201 {
1202     host->dma.xfer_required = 0;
1203 
1204     if (host->dma.direction == DMA_IN)
1205     acornscsi_data_read(host, host->dma.xfer_ptr,
1206                 host->dma.xfer_start, host->dma.xfer_length);
1207 }
1208 
1209 /*
1210  * Function: void acornscsi_dma_adjust(AS_Host *host)
1211  * Purpose : adjust DMA pointers & count for bytes transferred to
1212  *       SBIC but not SCSI bus.
1213  * Params  : host - host to adjust DMA count for
1214  */
1215 static
1216 void acornscsi_dma_adjust(AS_Host *host)
1217 {
1218     if (host->dma.xfer_setup) {
1219     signed long transferred;
1220 #if (DEBUG & (DEBUG_DMA|DEBUG_WRITE))
1221     DBG(host->SCpnt, acornscsi_dumpdma(host, "adji"));
1222 #endif
1223     /*
1224      * Calculate correct DMA address - DMA is ahead of SCSI bus while
1225      * writing.
1226      *  host->scsi.SCp.scsi_xferred is the number of bytes
1227      *  actually transferred to/from the SCSI bus.
1228      *  host->dma.transferred is the number of bytes transferred
1229      *  over DMA since host->dma.start_addr was last set.
1230      *
1231      * real_dma_addr = host->dma.start_addr + host->scsi.SCp.scsi_xferred
1232      *         - host->dma.transferred
1233      */
1234     transferred = host->scsi.SCp.scsi_xferred - host->dma.transferred;
1235     if (transferred < 0)
1236         printk("scsi%d.%c: Ack! DMA write correction %ld < 0!\n",
1237             host->host->host_no, acornscsi_target(host), transferred);
1238     else if (transferred == 0)
1239         host->dma.xfer_setup = 0;
1240     else {
1241         transferred += host->dma.start_addr;
1242         dmac_write(host, DMAC_TXADRLO, transferred);
1243         dmac_write(host, DMAC_TXADRMD, transferred >> 8);
1244         dmac_write(host, DMAC_TXADRHI, transferred >> 16);
1245 #if (DEBUG & (DEBUG_DMA|DEBUG_WRITE))
1246         DBG(host->SCpnt, acornscsi_dumpdma(host, "adjo"));
1247 #endif
1248     }
1249     }
1250 }
1251 #endif
1252 
1253 /* =========================================================================================
1254  * Data I/O
1255  */
1256 static int
1257 acornscsi_write_pio(AS_Host *host, char *bytes, int *ptr, int len, unsigned int max_timeout)
1258 {
1259     unsigned int asr, timeout = max_timeout;
1260     int my_ptr = *ptr;
1261 
1262     while (my_ptr < len) {
1263         asr = sbic_arm_read(host, SBIC_ASR);
1264 
1265         if (asr & ASR_DBR) {
1266             timeout = max_timeout;
1267 
1268             sbic_arm_write(host, SBIC_DATA, bytes[my_ptr++]);
1269         } else if (asr & ASR_INT)
1270             break;
1271         else if (--timeout == 0)
1272             break;
1273         udelay(1);
1274     }
1275 
1276     *ptr = my_ptr;
1277 
1278     return (timeout == 0) ? -1 : 0;
1279 }
1280 
1281 /*
1282  * Function: void acornscsi_sendcommand(AS_Host *host)
1283  * Purpose : send a command to a target
1284  * Params  : host - host which is connected to target
1285  */
1286 static void
1287 acornscsi_sendcommand(AS_Host *host)
1288 {
1289     struct scsi_cmnd *SCpnt = host->SCpnt;
1290 
1291     sbic_arm_write(host, SBIC_TRANSCNTH, 0);
1292     sbic_arm_writenext(host, 0);
1293     sbic_arm_writenext(host, SCpnt->cmd_len - host->scsi.SCp.sent_command);
1294 
1295     acornscsi_sbic_issuecmd(host, CMND_XFERINFO);
1296 
1297     if (acornscsi_write_pio(host, SCpnt->cmnd,
1298     (int *)&host->scsi.SCp.sent_command, SCpnt->cmd_len, 1000000))
1299     printk("scsi%d: timeout while sending command\n", host->host->host_no);
1300 
1301     host->scsi.phase = PHASE_COMMAND;
1302 }
1303 
1304 static
1305 void acornscsi_sendmessage(AS_Host *host)
1306 {
1307     unsigned int message_length = msgqueue_msglength(&host->scsi.msgs);
1308     unsigned int msgnr;
1309     struct message *msg;
1310 
1311 #if (DEBUG & DEBUG_MESSAGES)
1312     printk("scsi%d.%c: sending message ",
1313         host->host->host_no, acornscsi_target(host));
1314 #endif
1315 
1316     switch (message_length) {
1317     case 0:
1318     acornscsi_sbic_issuecmd(host, CMND_XFERINFO | CMND_SBT);
1319 
1320     acornscsi_sbic_wait(host, ASR_DBR, ASR_DBR, 1000, "sending message 1");
1321 
1322     sbic_arm_write(host, SBIC_DATA, NOP);
1323 
1324     host->scsi.last_message = NOP;
1325 #if (DEBUG & DEBUG_MESSAGES)
1326     printk("NOP");
1327 #endif
1328     break;
1329 
1330     case 1:
1331     acornscsi_sbic_issuecmd(host, CMND_XFERINFO | CMND_SBT);
1332     msg = msgqueue_getmsg(&host->scsi.msgs, 0);
1333 
1334     acornscsi_sbic_wait(host, ASR_DBR, ASR_DBR, 1000, "sending message 2");
1335 
1336     sbic_arm_write(host, SBIC_DATA, msg->msg[0]);
1337 
1338     host->scsi.last_message = msg->msg[0];
1339 #if (DEBUG & DEBUG_MESSAGES)
1340     spi_print_msg(msg->msg);
1341 #endif
1342     break;
1343 
1344     default:
1345     /*
1346      * ANSI standard says: (SCSI-2 Rev 10c Sect 5.6.14)
1347      * 'When a target sends this (MESSAGE_REJECT) message, it
1348      *  shall change to MESSAGE IN phase and send this message
1349      *  prior to requesting additional message bytes from the
1350      *  initiator.  This provides an interlock so that the
1351      *  initiator can determine which message byte is rejected.
1352      */
1353     sbic_arm_write(host, SBIC_TRANSCNTH, 0);
1354     sbic_arm_writenext(host, 0);
1355     sbic_arm_writenext(host, message_length);
1356     acornscsi_sbic_issuecmd(host, CMND_XFERINFO);
1357 
1358     msgnr = 0;
1359     while ((msg = msgqueue_getmsg(&host->scsi.msgs, msgnr++)) != NULL) {
1360         unsigned int i;
1361 #if (DEBUG & DEBUG_MESSAGES)
1362         spi_print_msg(msg);
1363 #endif
1364         i = 0;
1365         if (acornscsi_write_pio(host, msg->msg, &i, msg->length, 1000000))
1366         printk("scsi%d: timeout while sending message\n", host->host->host_no);
1367 
1368         host->scsi.last_message = msg->msg[0];
1369         if (msg->msg[0] == EXTENDED_MESSAGE)
1370         host->scsi.last_message |= msg->msg[2] << 8;
1371 
1372         if (i != msg->length)
1373         break;
1374     }
1375     break;
1376     }
1377 #if (DEBUG & DEBUG_MESSAGES)
1378     printk("\n");
1379 #endif
1380 }
1381 
1382 /*
1383  * Function: void acornscsi_readstatusbyte(AS_Host *host)
1384  * Purpose : Read status byte from connected target
1385  * Params  : host - host connected to target
1386  */
1387 static
1388 void acornscsi_readstatusbyte(AS_Host *host)
1389 {
1390     acornscsi_sbic_issuecmd(host, CMND_XFERINFO|CMND_SBT);
1391     acornscsi_sbic_wait(host, ASR_DBR, ASR_DBR, 1000, "reading status byte");
1392     host->scsi.SCp.Status = sbic_arm_read(host, SBIC_DATA);
1393 }
1394 
1395 /*
1396  * Function: unsigned char acornscsi_readmessagebyte(AS_Host *host)
1397  * Purpose : Read one message byte from connected target
1398  * Params  : host - host connected to target
1399  */
1400 static
1401 unsigned char acornscsi_readmessagebyte(AS_Host *host)
1402 {
1403     unsigned char message;
1404 
1405     acornscsi_sbic_issuecmd(host, CMND_XFERINFO | CMND_SBT);
1406 
1407     acornscsi_sbic_wait(host, ASR_DBR, ASR_DBR, 1000, "for message byte");
1408 
1409     message = sbic_arm_read(host, SBIC_DATA);
1410 
1411     /* wait for MSGIN-XFER-PAUSED */
1412     acornscsi_sbic_wait(host, ASR_INT, ASR_INT, 1000, "for interrupt after message byte");
1413 
1414     sbic_arm_read(host, SBIC_SSR);
1415 
1416     return message;
1417 }
1418 
1419 /*
1420  * Function: void acornscsi_message(AS_Host *host)
1421  * Purpose : Read complete message from connected target & action message
1422  * Params  : host - host connected to target
1423  */
1424 static
1425 void acornscsi_message(AS_Host *host)
1426 {
1427     struct scsi_pointer *scsi_pointer;
1428     unsigned char message[16];
1429     unsigned int msgidx = 0, msglen = 1;
1430 
1431     do {
1432     message[msgidx] = acornscsi_readmessagebyte(host);
1433 
1434     switch (msgidx) {
1435     case 0:
1436         if (message[0] == EXTENDED_MESSAGE ||
1437         (message[0] >= 0x20 && message[0] <= 0x2f))
1438         msglen = 2;
1439         break;
1440 
1441     case 1:
1442         if (message[0] == EXTENDED_MESSAGE)
1443         msglen += message[msgidx];
1444         break;
1445     }
1446     msgidx += 1;
1447     if (msgidx < msglen) {
1448         acornscsi_sbic_issuecmd(host, CMND_NEGATEACK);
1449 
1450         /* wait for next msg-in */
1451         acornscsi_sbic_wait(host, ASR_INT, ASR_INT, 1000, "for interrupt after negate ack");
1452         sbic_arm_read(host, SBIC_SSR);
1453     }
1454     } while (msgidx < msglen);
1455 
1456 #if (DEBUG & DEBUG_MESSAGES)
1457     printk("scsi%d.%c: message in: ",
1458         host->host->host_no, acornscsi_target(host));
1459     spi_print_msg(message);
1460     printk("\n");
1461 #endif
1462 
1463     if (host->scsi.phase == PHASE_RECONNECTED) {
1464     /*
1465      * ANSI standard says: (Section SCSI-2 Rev. 10c Sect 5.6.17)
1466      * 'Whenever a target reconnects to an initiator to continue
1467      *  a tagged I/O process, the SIMPLE QUEUE TAG message shall
1468      *  be sent immediately following the IDENTIFY message...'
1469      */
1470     if (message[0] == SIMPLE_QUEUE_TAG)
1471         host->scsi.reconnected.tag = message[1];
1472     if (acornscsi_reconnect_finish(host))
1473         host->scsi.phase = PHASE_MSGIN;
1474     }
1475 
1476     switch (message[0]) {
1477     case ABORT_TASK_SET:
1478     case ABORT_TASK:
1479     case COMMAND_COMPLETE:
1480     if (host->scsi.phase != PHASE_STATUSIN) {
1481         printk(KERN_ERR "scsi%d.%c: command complete following non-status in phase?\n",
1482             host->host->host_no, acornscsi_target(host));
1483         acornscsi_dumplog(host, host->SCpnt->device->id);
1484     }
1485     host->scsi.phase = PHASE_DONE;
1486     host->scsi.SCp.Message = message[0];
1487     break;
1488 
1489     case SAVE_POINTERS:
1490     /*
1491      * ANSI standard says: (Section SCSI-2 Rev. 10c Sect 5.6.20)
1492      * 'The SAVE DATA POINTER message is sent from a target to
1493      *  direct the initiator to copy the active data pointer to
1494      *  the saved data pointer for the current I/O process.
1495      */
1496     acornscsi_dma_cleanup(host);
1497     scsi_pointer = arm_scsi_pointer(host->SCpnt);
1498     *scsi_pointer = host->scsi.SCp;
1499     scsi_pointer->sent_command = 0;
1500     host->scsi.phase = PHASE_MSGIN;
1501     break;
1502 
1503     case RESTORE_POINTERS:
1504     /*
1505      * ANSI standard says: (Section SCSI-2 Rev. 10c Sect 5.6.19)
1506      * 'The RESTORE POINTERS message is sent from a target to
1507      *  direct the initiator to copy the most recently saved
1508      *  command, data, and status pointers for the I/O process
1509      *  to the corresponding active pointers.  The command and
1510      *  status pointers shall be restored to the beginning of
1511      *  the present command and status areas.'
1512      */
1513     acornscsi_dma_cleanup(host);
1514     host->scsi.SCp = *arm_scsi_pointer(host->SCpnt);
1515     host->scsi.phase = PHASE_MSGIN;
1516     break;
1517 
1518     case DISCONNECT:
1519     /*
1520      * ANSI standard says: (Section SCSI-2 Rev. 10c Sect 6.4.2)
1521      * 'On those occasions when an error or exception condition occurs
1522      *  and the target elects to repeat the information transfer, the
1523      *  target may repeat the transfer either issuing a RESTORE POINTERS
1524      *  message or by disconnecting without issuing a SAVE POINTERS
1525      *  message.  When reconnection is completed, the most recent
1526      *  saved pointer values are restored.'
1527      */
1528     acornscsi_dma_cleanup(host);
1529     host->scsi.phase = PHASE_DISCONNECT;
1530     break;
1531 
1532     case MESSAGE_REJECT:
1533 #if 0 /* this isn't needed any more */
1534     /*
1535      * If we were negociating sync transfer, we don't yet know if
1536      * this REJECT is for the sync transfer or for the tagged queue/wide
1537      * transfer.  Re-initiate sync transfer negotiation now, and if
1538      * we got a REJECT in response to SDTR, then it'll be set to DONE.
1539      */
1540     if (host->device[host->SCpnt->device->id].sync_state == SYNC_SENT_REQUEST)
1541         host->device[host->SCpnt->device->id].sync_state = SYNC_NEGOCIATE;
1542 #endif
1543 
1544     /*
1545      * If we have any messages waiting to go out, then assert ATN now
1546      */
1547     if (msgqueue_msglength(&host->scsi.msgs))
1548         acornscsi_sbic_issuecmd(host, CMND_ASSERTATN);
1549 
1550     switch (host->scsi.last_message) {
1551     case EXTENDED_MESSAGE | (EXTENDED_SDTR << 8):
1552         /*
1553          * Target can't handle synchronous transfers
1554          */
1555         printk(KERN_NOTICE "scsi%d.%c: Using asynchronous transfer\n",
1556             host->host->host_no, acornscsi_target(host));
1557         host->device[host->SCpnt->device->id].sync_xfer = SYNCHTRANSFER_2DBA;
1558         host->device[host->SCpnt->device->id].sync_state = SYNC_ASYNCHRONOUS;
1559         sbic_arm_write(host, SBIC_SYNCHTRANSFER, host->device[host->SCpnt->device->id].sync_xfer);
1560         break;
1561 
1562     default:
1563         break;
1564     }
1565     break;
1566 
1567     case SIMPLE_QUEUE_TAG:
1568     /* tag queue reconnect... message[1] = queue tag.  Print something to indicate something happened! */
1569     printk("scsi%d.%c: reconnect queue tag %02X\n",
1570         host->host->host_no, acornscsi_target(host),
1571         message[1]);
1572     break;
1573 
1574     case EXTENDED_MESSAGE:
1575     switch (message[2]) {
1576 #ifdef CONFIG_SCSI_ACORNSCSI_SYNC
1577     case EXTENDED_SDTR:
1578         if (host->device[host->SCpnt->device->id].sync_state == SYNC_SENT_REQUEST) {
1579         /*
1580          * We requested synchronous transfers.  This isn't quite right...
1581          * We can only say if this succeeded if we proceed on to execute the
1582          * command from this message.  If we get a MESSAGE PARITY ERROR,
1583          * and the target retries fail, then we fallback to asynchronous mode
1584          */
1585         host->device[host->SCpnt->device->id].sync_state = SYNC_COMPLETED;
1586         printk(KERN_NOTICE "scsi%d.%c: Using synchronous transfer, offset %d, %d ns\n",
1587             host->host->host_no, acornscsi_target(host),
1588             message[4], message[3] * 4);
1589         host->device[host->SCpnt->device->id].sync_xfer =
1590             calc_sync_xfer(message[3] * 4, message[4]);
1591         } else {
1592         unsigned char period, length;
1593         /*
1594          * Target requested synchronous transfers.  The agreement is only
1595          * to be in operation AFTER the target leaves message out phase.
1596          */
1597         acornscsi_sbic_issuecmd(host, CMND_ASSERTATN);
1598         period = max_t(unsigned int, message[3], sdtr_period / 4);
1599         length = min_t(unsigned int, message[4], sdtr_size);
1600         msgqueue_addmsg(&host->scsi.msgs, 5, EXTENDED_MESSAGE, 3,
1601                  EXTENDED_SDTR, period, length);
1602         host->device[host->SCpnt->device->id].sync_xfer =
1603             calc_sync_xfer(period * 4, length);
1604         }
1605         sbic_arm_write(host, SBIC_SYNCHTRANSFER, host->device[host->SCpnt->device->id].sync_xfer);
1606         break;
1607 #else
1608         /* We do not accept synchronous transfers.  Respond with a
1609          * MESSAGE_REJECT.
1610          */
1611 #endif
1612 
1613     case EXTENDED_WDTR:
1614         /* The WD33C93A is only 8-bit.  We respond with a MESSAGE_REJECT
1615          * to a wide data transfer request.
1616          */
1617     default:
1618         acornscsi_sbic_issuecmd(host, CMND_ASSERTATN);
1619         msgqueue_flush(&host->scsi.msgs);
1620         msgqueue_addmsg(&host->scsi.msgs, 1, MESSAGE_REJECT);
1621         break;
1622     }
1623     break;
1624 
1625     default: /* reject message */
1626     printk(KERN_ERR "scsi%d.%c: unrecognised message %02X, rejecting\n",
1627         host->host->host_no, acornscsi_target(host),
1628         message[0]);
1629     acornscsi_sbic_issuecmd(host, CMND_ASSERTATN);
1630     msgqueue_flush(&host->scsi.msgs);
1631     msgqueue_addmsg(&host->scsi.msgs, 1, MESSAGE_REJECT);
1632     host->scsi.phase = PHASE_MSGIN;
1633     break;
1634     }
1635     acornscsi_sbic_issuecmd(host, CMND_NEGATEACK);
1636 }
1637 
1638 /*
1639  * Function: int acornscsi_buildmessages(AS_Host *host)
1640  * Purpose : build the connection messages for a host
1641  * Params  : host - host to add messages to
1642  */
1643 static
1644 void acornscsi_buildmessages(AS_Host *host)
1645 {
1646 #if 0
1647     /* does the device need resetting? */
1648     if (cmd_reset) {
1649     msgqueue_addmsg(&host->scsi.msgs, 1, BUS_DEVICE_RESET);
1650     return;
1651     }
1652 #endif
1653 
1654     msgqueue_addmsg(&host->scsi.msgs, 1,
1655              IDENTIFY(host->device[host->SCpnt->device->id].disconnect_ok,
1656                  host->SCpnt->device->lun));
1657 
1658 #if 0
1659     /* does the device need the current command aborted */
1660     if (cmd_aborted) {
1661     acornscsi_abortcmd(host);
1662     return;
1663     }
1664 #endif
1665 
1666 
1667 #ifdef CONFIG_SCSI_ACORNSCSI_SYNC
1668     if (host->device[host->SCpnt->device->id].sync_state == SYNC_NEGOCIATE) {
1669     host->device[host->SCpnt->device->id].sync_state = SYNC_SENT_REQUEST;
1670     msgqueue_addmsg(&host->scsi.msgs, 5,
1671              EXTENDED_MESSAGE, 3, EXTENDED_SDTR,
1672              sdtr_period / 4, sdtr_size);
1673     }
1674 #endif
1675 }
1676 
1677 /*
1678  * Function: int acornscsi_starttransfer(AS_Host *host)
1679  * Purpose : transfer data to/from connected target
1680  * Params  : host - host to which target is connected
1681  * Returns : 0 if failure
1682  */
1683 static
1684 int acornscsi_starttransfer(AS_Host *host)
1685 {
1686     int residual;
1687 
1688     if (!host->scsi.SCp.ptr /*&& host->scsi.SCp.this_residual*/) {
1689     printk(KERN_ERR "scsi%d.%c: null buffer passed to acornscsi_starttransfer\n",
1690         host->host->host_no, acornscsi_target(host));
1691     return 0;
1692     }
1693 
1694     residual = scsi_bufflen(host->SCpnt) - host->scsi.SCp.scsi_xferred;
1695 
1696     sbic_arm_write(host, SBIC_SYNCHTRANSFER, host->device[host->SCpnt->device->id].sync_xfer);
1697     sbic_arm_writenext(host, residual >> 16);
1698     sbic_arm_writenext(host, residual >> 8);
1699     sbic_arm_writenext(host, residual);
1700     acornscsi_sbic_issuecmd(host, CMND_XFERINFO);
1701     return 1;
1702 }
1703 
1704 /* =========================================================================================
1705  * Connection & Disconnection
1706  */
1707 /*
1708  * Function : acornscsi_reconnect(AS_Host *host)
1709  * Purpose  : reconnect a previously disconnected command
1710  * Params   : host - host specific data
1711  * Remarks  : SCSI spec says:
1712  *      'The set of active pointers is restored from the set
1713  *       of saved pointers upon reconnection of the I/O process'
1714  */
1715 static
1716 int acornscsi_reconnect(AS_Host *host)
1717 {
1718     unsigned int target, lun, ok = 0;
1719 
1720     target = sbic_arm_read(host, SBIC_SOURCEID);
1721 
1722     if (!(target & 8))
1723     printk(KERN_ERR "scsi%d: invalid source id after reselection "
1724         "- device fault?\n",
1725         host->host->host_no);
1726 
1727     target &= 7;
1728 
1729     if (host->SCpnt && !host->scsi.disconnectable) {
1730     printk(KERN_ERR "scsi%d.%d: reconnected while command in "
1731         "progress to target %d?\n",
1732         host->host->host_no, target, host->SCpnt->device->id);
1733     host->SCpnt = NULL;
1734     }
1735 
1736     lun = sbic_arm_read(host, SBIC_DATA) & 7;
1737 
1738     host->scsi.reconnected.target = target;
1739     host->scsi.reconnected.lun = lun;
1740     host->scsi.reconnected.tag = 0;
1741 
1742     if (host->scsi.disconnectable && host->SCpnt &&
1743     host->SCpnt->device->id == target && host->SCpnt->device->lun == lun)
1744     ok = 1;
1745 
1746     if (!ok && queue_probetgtlun(&host->queues.disconnected, target, lun))
1747     ok = 1;
1748 
1749     ADD_STATUS(target, 0x81, host->scsi.phase, 0);
1750 
1751     if (ok) {
1752     host->scsi.phase = PHASE_RECONNECTED;
1753     } else {
1754     /* this doesn't seem to work */
1755     printk(KERN_ERR "scsi%d.%c: reselected with no command "
1756         "to reconnect with\n",
1757         host->host->host_no, '0' + target);
1758     acornscsi_dumplog(host, target);
1759     acornscsi_abortcmd(host);
1760     if (host->SCpnt) {
1761         queue_add_cmd_tail(&host->queues.disconnected, host->SCpnt);
1762         host->SCpnt = NULL;
1763     }
1764     }
1765     acornscsi_sbic_issuecmd(host, CMND_NEGATEACK);
1766     return !ok;
1767 }
1768 
1769 /*
1770  * Function: int acornscsi_reconnect_finish(AS_Host *host)
1771  * Purpose : finish reconnecting a command
1772  * Params  : host - host to complete
1773  * Returns : 0 if failed
1774  */
1775 static
1776 int acornscsi_reconnect_finish(AS_Host *host)
1777 {
1778     if (host->scsi.disconnectable && host->SCpnt) {
1779     host->scsi.disconnectable = 0;
1780     if (host->SCpnt->device->id  == host->scsi.reconnected.target &&
1781         host->SCpnt->device->lun == host->scsi.reconnected.lun &&
1782         scsi_cmd_to_rq(host->SCpnt)->tag == host->scsi.reconnected.tag) {
1783 #if (DEBUG & (DEBUG_QUEUES|DEBUG_DISCON))
1784         DBG(host->SCpnt, printk("scsi%d.%c: reconnected",
1785             host->host->host_no, acornscsi_target(host)));
1786 #endif
1787     } else {
1788         queue_add_cmd_tail(&host->queues.disconnected, host->SCpnt);
1789 #if (DEBUG & (DEBUG_QUEUES|DEBUG_DISCON))
1790         DBG(host->SCpnt, printk("scsi%d.%c: had to move command "
1791             "to disconnected queue\n",
1792             host->host->host_no, acornscsi_target(host)));
1793 #endif
1794         host->SCpnt = NULL;
1795     }
1796     }
1797     if (!host->SCpnt) {
1798     host->SCpnt = queue_remove_tgtluntag(&host->queues.disconnected,
1799                 host->scsi.reconnected.target,
1800                 host->scsi.reconnected.lun,
1801                 host->scsi.reconnected.tag);
1802 #if (DEBUG & (DEBUG_QUEUES|DEBUG_DISCON))
1803     DBG(host->SCpnt, printk("scsi%d.%c: had to get command",
1804         host->host->host_no, acornscsi_target(host)));
1805 #endif
1806     }
1807 
1808     if (!host->SCpnt)
1809     acornscsi_abortcmd(host);
1810     else {
1811     /*
1812      * Restore data pointer from SAVED pointers.
1813      */
1814     host->scsi.SCp = *arm_scsi_pointer(host->SCpnt);
1815 #if (DEBUG & (DEBUG_QUEUES|DEBUG_DISCON))
1816     printk(", data pointers: [%p, %X]",
1817         host->scsi.SCp.ptr, host->scsi.SCp.this_residual);
1818 #endif
1819     }
1820 #if (DEBUG & (DEBUG_QUEUES|DEBUG_DISCON))
1821     printk("\n");
1822 #endif
1823 
1824     host->dma.transferred = host->scsi.SCp.scsi_xferred;
1825 
1826     return host->SCpnt != NULL;
1827 }
1828 
1829 /*
1830  * Function: void acornscsi_disconnect_unexpected(AS_Host *host)
1831  * Purpose : handle an unexpected disconnect
1832  * Params  : host - host on which disconnect occurred
1833  */
1834 static
1835 void acornscsi_disconnect_unexpected(AS_Host *host)
1836 {
1837     printk(KERN_ERR "scsi%d.%c: unexpected disconnect\n",
1838         host->host->host_no, acornscsi_target(host));
1839 #if (DEBUG & DEBUG_ABORT)
1840     acornscsi_dumplog(host, 8);
1841 #endif
1842 
1843     acornscsi_done(host, &host->SCpnt, DID_ERROR);
1844 }
1845 
1846 /*
1847  * Function: void acornscsi_abortcmd(AS_host *host, unsigned char tag)
1848  * Purpose : abort a currently executing command
1849  * Params  : host - host with connected command to abort
1850  */
1851 static
1852 void acornscsi_abortcmd(AS_Host *host)
1853 {
1854     host->scsi.phase = PHASE_ABORTED;
1855     sbic_arm_write(host, SBIC_CMND, CMND_ASSERTATN);
1856 
1857     msgqueue_flush(&host->scsi.msgs);
1858     msgqueue_addmsg(&host->scsi.msgs, 1, ABORT);
1859 }
1860 
1861 /* ==========================================================================================
1862  * Interrupt routines.
1863  */
1864 /*
1865  * Function: int acornscsi_sbicintr(AS_Host *host)
1866  * Purpose : handle interrupts from SCSI device
1867  * Params  : host - host to process
1868  * Returns : INTR_PROCESS if expecting another SBIC interrupt
1869  *       INTR_IDLE if no interrupt
1870  *       INTR_NEXT_COMMAND if we have finished processing the command
1871  */
1872 static
1873 intr_ret_t acornscsi_sbicintr(AS_Host *host, int in_irq)
1874 {
1875     unsigned int asr, ssr;
1876 
1877     asr = sbic_arm_read(host, SBIC_ASR);
1878     if (!(asr & ASR_INT))
1879     return INTR_IDLE;
1880 
1881     ssr = sbic_arm_read(host, SBIC_SSR);
1882 
1883 #if (DEBUG & DEBUG_PHASES)
1884     print_sbic_status(asr, ssr, host->scsi.phase);
1885 #endif
1886 
1887     ADD_STATUS(8, ssr, host->scsi.phase, in_irq);
1888 
1889     if (host->SCpnt && !host->scsi.disconnectable)
1890     ADD_STATUS(host->SCpnt->device->id, ssr, host->scsi.phase, in_irq);
1891 
1892     switch (ssr) {
1893     case 0x00:              /* reset state - not advanced           */
1894     printk(KERN_ERR "scsi%d: reset in standard mode but wanted advanced mode.\n",
1895         host->host->host_no);
1896     /* setup sbic - WD33C93A */
1897     sbic_arm_write(host, SBIC_OWNID, OWNID_EAF | host->host->this_id);
1898     sbic_arm_write(host, SBIC_CMND, CMND_RESET);
1899     return INTR_IDLE;
1900 
1901     case 0x01:              /* reset state - advanced           */
1902     sbic_arm_write(host, SBIC_CTRL, INIT_SBICDMA | CTRL_IDI);
1903     sbic_arm_write(host, SBIC_TIMEOUT, TIMEOUT_TIME);
1904     sbic_arm_write(host, SBIC_SYNCHTRANSFER, SYNCHTRANSFER_2DBA);
1905     sbic_arm_write(host, SBIC_SOURCEID, SOURCEID_ER | SOURCEID_DSP);
1906     msgqueue_flush(&host->scsi.msgs);
1907     return INTR_IDLE;
1908 
1909     case 0x41:              /* unexpected disconnect aborted command    */
1910     acornscsi_disconnect_unexpected(host);
1911     return INTR_NEXT_COMMAND;
1912     }
1913 
1914     switch (host->scsi.phase) {
1915     case PHASE_CONNECTING:      /* STATE: command removed from issue queue  */
1916     switch (ssr) {
1917     case 0x11:          /* -> PHASE_CONNECTED               */
1918         /* BUS FREE -> SELECTION */
1919         host->scsi.phase = PHASE_CONNECTED;
1920         msgqueue_flush(&host->scsi.msgs);
1921         host->dma.transferred = host->scsi.SCp.scsi_xferred;
1922         /* 33C93 gives next interrupt indicating bus phase */
1923         asr = sbic_arm_read(host, SBIC_ASR);
1924         if (!(asr & ASR_INT))
1925         break;
1926         ssr = sbic_arm_read(host, SBIC_SSR);
1927         ADD_STATUS(8, ssr, host->scsi.phase, 1);
1928         ADD_STATUS(host->SCpnt->device->id, ssr, host->scsi.phase, 1);
1929         goto connected;
1930         
1931     case 0x42:          /* select timed out             */
1932                     /* -> PHASE_IDLE                */
1933         acornscsi_done(host, &host->SCpnt, DID_NO_CONNECT);
1934         return INTR_NEXT_COMMAND;
1935 
1936     case 0x81:          /* -> PHASE_RECONNECTED or PHASE_ABORTED    */
1937         /* BUS FREE -> RESELECTION */
1938         host->origSCpnt = host->SCpnt;
1939         host->SCpnt = NULL;
1940         msgqueue_flush(&host->scsi.msgs);
1941         acornscsi_reconnect(host);
1942         break;
1943 
1944     default:
1945         printk(KERN_ERR "scsi%d.%c: PHASE_CONNECTING, SSR %02X?\n",
1946             host->host->host_no, acornscsi_target(host), ssr);
1947         acornscsi_dumplog(host, host->SCpnt ? host->SCpnt->device->id : 8);
1948         acornscsi_abortcmd(host);
1949     }
1950     return INTR_PROCESSING;
1951 
1952     connected:
1953     case PHASE_CONNECTED:       /* STATE: device selected ok            */
1954     switch (ssr) {
1955 #ifdef NONSTANDARD
1956     case 0x8a:          /* -> PHASE_COMMAND, PHASE_COMMANDPAUSED    */
1957         /* SELECTION -> COMMAND */
1958         acornscsi_sendcommand(host);
1959         break;
1960 
1961     case 0x8b:          /* -> PHASE_STATUS              */
1962         /* SELECTION -> STATUS */
1963         acornscsi_readstatusbyte(host);
1964         host->scsi.phase = PHASE_STATUSIN;
1965         break;
1966 #endif
1967 
1968     case 0x8e:          /* -> PHASE_MSGOUT              */
1969         /* SELECTION ->MESSAGE OUT */
1970         host->scsi.phase = PHASE_MSGOUT;
1971         acornscsi_buildmessages(host);
1972         acornscsi_sendmessage(host);
1973         break;
1974 
1975     /* these should not happen */
1976     case 0x85:          /* target disconnected              */
1977         acornscsi_done(host, &host->SCpnt, DID_ERROR);
1978         break;
1979 
1980     default:
1981         printk(KERN_ERR "scsi%d.%c: PHASE_CONNECTED, SSR %02X?\n",
1982             host->host->host_no, acornscsi_target(host), ssr);
1983         acornscsi_dumplog(host, host->SCpnt ? host->SCpnt->device->id : 8);
1984         acornscsi_abortcmd(host);
1985     }
1986     return INTR_PROCESSING;
1987 
1988     case PHASE_MSGOUT:          /* STATE: connected & sent IDENTIFY message */
1989     /*
1990      * SCSI standard says that MESSAGE OUT phases can be followed by a
1991      * DATA phase, STATUS phase, MESSAGE IN phase or COMMAND phase
1992      */
1993     switch (ssr) {
1994     case 0x8a:          /* -> PHASE_COMMAND, PHASE_COMMANDPAUSED    */
1995     case 0x1a:          /* -> PHASE_COMMAND, PHASE_COMMANDPAUSED    */
1996         /* MESSAGE OUT -> COMMAND */
1997         acornscsi_sendcommand(host);
1998         break;
1999 
2000     case 0x8b:          /* -> PHASE_STATUS              */
2001     case 0x1b:          /* -> PHASE_STATUS              */
2002         /* MESSAGE OUT -> STATUS */
2003         acornscsi_readstatusbyte(host);
2004         host->scsi.phase = PHASE_STATUSIN;
2005         break;
2006 
2007     case 0x8e:          /* -> PHASE_MSGOUT              */
2008         /* MESSAGE_OUT(MESSAGE_IN) ->MESSAGE OUT */
2009         acornscsi_sendmessage(host);
2010         break;
2011 
2012     case 0x4f:          /* -> PHASE_MSGIN, PHASE_DISCONNECT     */
2013     case 0x1f:          /* -> PHASE_MSGIN, PHASE_DISCONNECT     */
2014         /* MESSAGE OUT -> MESSAGE IN */
2015         acornscsi_message(host);
2016         break;
2017 
2018     default:
2019         printk(KERN_ERR "scsi%d.%c: PHASE_MSGOUT, SSR %02X?\n",
2020             host->host->host_no, acornscsi_target(host), ssr);
2021         acornscsi_dumplog(host, host->SCpnt ? host->SCpnt->device->id : 8);
2022     }
2023     return INTR_PROCESSING;
2024 
2025     case PHASE_COMMAND:         /* STATE: connected & command sent      */
2026     switch (ssr) {
2027     case 0x18:          /* -> PHASE_DATAOUT             */
2028         /* COMMAND -> DATA OUT */
2029         if (host->scsi.SCp.sent_command != host->SCpnt->cmd_len)
2030         acornscsi_abortcmd(host);
2031         acornscsi_dma_setup(host, DMA_OUT);
2032         if (!acornscsi_starttransfer(host))
2033         acornscsi_abortcmd(host);
2034         host->scsi.phase = PHASE_DATAOUT;
2035         return INTR_IDLE;
2036 
2037     case 0x19:          /* -> PHASE_DATAIN              */
2038         /* COMMAND -> DATA IN */
2039         if (host->scsi.SCp.sent_command != host->SCpnt->cmd_len)
2040         acornscsi_abortcmd(host);
2041         acornscsi_dma_setup(host, DMA_IN);
2042         if (!acornscsi_starttransfer(host))
2043         acornscsi_abortcmd(host);
2044         host->scsi.phase = PHASE_DATAIN;
2045         return INTR_IDLE;
2046 
2047     case 0x1b:          /* -> PHASE_STATUS              */
2048         /* COMMAND -> STATUS */
2049         acornscsi_readstatusbyte(host);
2050         host->scsi.phase = PHASE_STATUSIN;
2051         break;
2052 
2053     case 0x1e:          /* -> PHASE_MSGOUT              */
2054         /* COMMAND -> MESSAGE OUT */
2055         acornscsi_sendmessage(host);
2056         break;
2057 
2058     case 0x1f:          /* -> PHASE_MSGIN, PHASE_DISCONNECT     */
2059         /* COMMAND -> MESSAGE IN */
2060         acornscsi_message(host);
2061         break;
2062 
2063     default:
2064         printk(KERN_ERR "scsi%d.%c: PHASE_COMMAND, SSR %02X?\n",
2065             host->host->host_no, acornscsi_target(host), ssr);
2066         acornscsi_dumplog(host, host->SCpnt ? host->SCpnt->device->id : 8);
2067     }
2068     return INTR_PROCESSING;
2069 
2070     case PHASE_DISCONNECT:      /* STATE: connected, received DISCONNECT msg    */
2071     if (ssr == 0x85) {      /* -> PHASE_IDLE                */
2072         host->scsi.disconnectable = 1;
2073         host->scsi.reconnected.tag = 0;
2074         host->scsi.phase = PHASE_IDLE;
2075         host->stats.disconnects += 1;
2076     } else {
2077         printk(KERN_ERR "scsi%d.%c: PHASE_DISCONNECT, SSR %02X instead of disconnect?\n",
2078             host->host->host_no, acornscsi_target(host), ssr);
2079         acornscsi_dumplog(host, host->SCpnt ? host->SCpnt->device->id : 8);
2080     }
2081     return INTR_NEXT_COMMAND;
2082 
2083     case PHASE_IDLE:            /* STATE: disconnected              */
2084     if (ssr == 0x81)        /* -> PHASE_RECONNECTED or PHASE_ABORTED    */
2085         acornscsi_reconnect(host);
2086     else {
2087         printk(KERN_ERR "scsi%d.%c: PHASE_IDLE, SSR %02X while idle?\n",
2088             host->host->host_no, acornscsi_target(host), ssr);
2089         acornscsi_dumplog(host, host->SCpnt ? host->SCpnt->device->id : 8);
2090     }
2091     return INTR_PROCESSING;
2092 
2093     case PHASE_RECONNECTED:     /* STATE: device reconnected to initiator   */
2094     /*
2095      * Command reconnected - if MESGIN, get message - it may be
2096      * the tag.  If not, get command out of disconnected queue
2097      */
2098     /*
2099      * If we reconnected and we're not in MESSAGE IN phase after IDENTIFY,
2100      * reconnect I_T_L command
2101      */
2102     if (ssr != 0x8f && !acornscsi_reconnect_finish(host))
2103         return INTR_IDLE;
2104     ADD_STATUS(host->SCpnt->device->id, ssr, host->scsi.phase, in_irq);
2105     switch (ssr) {
2106     case 0x88:          /* data out phase               */
2107                     /* -> PHASE_DATAOUT             */
2108         /* MESSAGE IN -> DATA OUT */
2109         acornscsi_dma_setup(host, DMA_OUT);
2110         if (!acornscsi_starttransfer(host))
2111         acornscsi_abortcmd(host);
2112         host->scsi.phase = PHASE_DATAOUT;
2113         return INTR_IDLE;
2114 
2115     case 0x89:          /* data in phase                */
2116                     /* -> PHASE_DATAIN              */
2117         /* MESSAGE IN -> DATA IN */
2118         acornscsi_dma_setup(host, DMA_IN);
2119         if (!acornscsi_starttransfer(host))
2120         acornscsi_abortcmd(host);
2121         host->scsi.phase = PHASE_DATAIN;
2122         return INTR_IDLE;
2123 
2124     case 0x8a:          /* command out                  */
2125         /* MESSAGE IN -> COMMAND */
2126         acornscsi_sendcommand(host);/* -> PHASE_COMMAND, PHASE_COMMANDPAUSED    */
2127         break;
2128 
2129     case 0x8b:          /* status in                    */
2130                     /* -> PHASE_STATUSIN                */
2131         /* MESSAGE IN -> STATUS */
2132         acornscsi_readstatusbyte(host);
2133         host->scsi.phase = PHASE_STATUSIN;
2134         break;
2135 
2136     case 0x8e:          /* message out                  */
2137                     /* -> PHASE_MSGOUT              */
2138         /* MESSAGE IN -> MESSAGE OUT */
2139         acornscsi_sendmessage(host);
2140         break;
2141 
2142     case 0x8f:          /* message in                   */
2143         acornscsi_message(host);    /* -> PHASE_MSGIN, PHASE_DISCONNECT     */
2144         break;
2145 
2146     default:
2147         printk(KERN_ERR "scsi%d.%c: PHASE_RECONNECTED, SSR %02X after reconnect?\n",
2148             host->host->host_no, acornscsi_target(host), ssr);
2149         acornscsi_dumplog(host, host->SCpnt ? host->SCpnt->device->id : 8);
2150     }
2151     return INTR_PROCESSING;
2152 
2153     case PHASE_DATAIN:          /* STATE: transferred data in           */
2154     /*
2155      * This is simple - if we disconnect then the DMA address & count is
2156      * correct.
2157      */
2158     switch (ssr) {
2159     case 0x19:          /* -> PHASE_DATAIN              */
2160     case 0x89:          /* -> PHASE_DATAIN              */
2161         acornscsi_abortcmd(host);
2162         return INTR_IDLE;
2163 
2164     case 0x1b:          /* -> PHASE_STATUSIN                */
2165     case 0x4b:          /* -> PHASE_STATUSIN                */
2166     case 0x8b:          /* -> PHASE_STATUSIN                */
2167         /* DATA IN -> STATUS */
2168         host->scsi.SCp.scsi_xferred = scsi_bufflen(host->SCpnt) -
2169                       acornscsi_sbic_xfcount(host);
2170         acornscsi_dma_stop(host);
2171         acornscsi_readstatusbyte(host);
2172         host->scsi.phase = PHASE_STATUSIN;
2173         break;
2174 
2175     case 0x1e:          /* -> PHASE_MSGOUT              */
2176     case 0x4e:          /* -> PHASE_MSGOUT              */
2177     case 0x8e:          /* -> PHASE_MSGOUT              */
2178         /* DATA IN -> MESSAGE OUT */
2179         host->scsi.SCp.scsi_xferred = scsi_bufflen(host->SCpnt) -
2180                       acornscsi_sbic_xfcount(host);
2181         acornscsi_dma_stop(host);
2182         acornscsi_sendmessage(host);
2183         break;
2184 
2185     case 0x1f:          /* message in                   */
2186     case 0x4f:          /* message in                   */
2187     case 0x8f:          /* message in                   */
2188         /* DATA IN -> MESSAGE IN */
2189         host->scsi.SCp.scsi_xferred = scsi_bufflen(host->SCpnt) -
2190                       acornscsi_sbic_xfcount(host);
2191         acornscsi_dma_stop(host);
2192         acornscsi_message(host);    /* -> PHASE_MSGIN, PHASE_DISCONNECT     */
2193         break;
2194 
2195     default:
2196         printk(KERN_ERR "scsi%d.%c: PHASE_DATAIN, SSR %02X?\n",
2197             host->host->host_no, acornscsi_target(host), ssr);
2198         acornscsi_dumplog(host, host->SCpnt ? host->SCpnt->device->id : 8);
2199     }
2200     return INTR_PROCESSING;
2201 
2202     case PHASE_DATAOUT:         /* STATE: transferred data out          */
2203     /*
2204      * This is more complicated - if we disconnect, the DMA could be 12
2205      * bytes ahead of us.  We need to correct this.
2206      */
2207     switch (ssr) {
2208     case 0x18:          /* -> PHASE_DATAOUT             */
2209     case 0x88:          /* -> PHASE_DATAOUT             */
2210         acornscsi_abortcmd(host);
2211         return INTR_IDLE;
2212 
2213     case 0x1b:          /* -> PHASE_STATUSIN                */
2214     case 0x4b:          /* -> PHASE_STATUSIN                */
2215     case 0x8b:          /* -> PHASE_STATUSIN                */
2216         /* DATA OUT -> STATUS */
2217         host->scsi.SCp.scsi_xferred = scsi_bufflen(host->SCpnt) -
2218                       acornscsi_sbic_xfcount(host);
2219         acornscsi_dma_stop(host);
2220         acornscsi_dma_adjust(host);
2221         acornscsi_readstatusbyte(host);
2222         host->scsi.phase = PHASE_STATUSIN;
2223         break;
2224 
2225     case 0x1e:          /* -> PHASE_MSGOUT              */
2226     case 0x4e:          /* -> PHASE_MSGOUT              */
2227     case 0x8e:          /* -> PHASE_MSGOUT              */
2228         /* DATA OUT -> MESSAGE OUT */
2229         host->scsi.SCp.scsi_xferred = scsi_bufflen(host->SCpnt) -
2230                       acornscsi_sbic_xfcount(host);
2231         acornscsi_dma_stop(host);
2232         acornscsi_dma_adjust(host);
2233         acornscsi_sendmessage(host);
2234         break;
2235 
2236     case 0x1f:          /* message in                   */
2237     case 0x4f:          /* message in                   */
2238     case 0x8f:          /* message in                   */
2239         /* DATA OUT -> MESSAGE IN */
2240         host->scsi.SCp.scsi_xferred = scsi_bufflen(host->SCpnt) -
2241                       acornscsi_sbic_xfcount(host);
2242         acornscsi_dma_stop(host);
2243         acornscsi_dma_adjust(host);
2244         acornscsi_message(host);    /* -> PHASE_MSGIN, PHASE_DISCONNECT     */
2245         break;
2246 
2247     default:
2248         printk(KERN_ERR "scsi%d.%c: PHASE_DATAOUT, SSR %02X?\n",
2249             host->host->host_no, acornscsi_target(host), ssr);
2250         acornscsi_dumplog(host, host->SCpnt ? host->SCpnt->device->id : 8);
2251     }
2252     return INTR_PROCESSING;
2253 
2254     case PHASE_STATUSIN:        /* STATE: status in complete            */
2255     switch (ssr) {
2256     case 0x1f:          /* -> PHASE_MSGIN, PHASE_DONE, PHASE_DISCONNECT */
2257     case 0x8f:          /* -> PHASE_MSGIN, PHASE_DONE, PHASE_DISCONNECT */
2258         /* STATUS -> MESSAGE IN */
2259         acornscsi_message(host);
2260         break;
2261 
2262     case 0x1e:          /* -> PHASE_MSGOUT              */
2263     case 0x8e:          /* -> PHASE_MSGOUT              */
2264         /* STATUS -> MESSAGE OUT */
2265         acornscsi_sendmessage(host);
2266         break;
2267 
2268     default:
2269         printk(KERN_ERR "scsi%d.%c: PHASE_STATUSIN, SSR %02X instead of MESSAGE_IN?\n",
2270             host->host->host_no, acornscsi_target(host), ssr);
2271         acornscsi_dumplog(host, host->SCpnt ? host->SCpnt->device->id : 8);
2272     }
2273     return INTR_PROCESSING;
2274 
2275     case PHASE_MSGIN:           /* STATE: message in                */
2276     switch (ssr) {
2277     case 0x1e:          /* -> PHASE_MSGOUT              */
2278     case 0x4e:          /* -> PHASE_MSGOUT              */
2279     case 0x8e:          /* -> PHASE_MSGOUT              */
2280         /* MESSAGE IN -> MESSAGE OUT */
2281         acornscsi_sendmessage(host);
2282         break;
2283 
2284     case 0x1f:          /* -> PHASE_MSGIN, PHASE_DONE, PHASE_DISCONNECT */
2285     case 0x2f:
2286     case 0x4f:
2287     case 0x8f:
2288         acornscsi_message(host);
2289         break;
2290 
2291     case 0x85:
2292         printk("scsi%d.%c: strange message in disconnection\n",
2293         host->host->host_no, acornscsi_target(host));
2294         acornscsi_dumplog(host, host->SCpnt ? host->SCpnt->device->id : 8);
2295         acornscsi_done(host, &host->SCpnt, DID_ERROR);
2296         break;
2297 
2298     default:
2299         printk(KERN_ERR "scsi%d.%c: PHASE_MSGIN, SSR %02X after message in?\n",
2300             host->host->host_no, acornscsi_target(host), ssr);
2301         acornscsi_dumplog(host, host->SCpnt ? host->SCpnt->device->id : 8);
2302     }
2303     return INTR_PROCESSING;
2304 
2305     case PHASE_DONE:            /* STATE: received status & message     */
2306     switch (ssr) {
2307     case 0x85:          /* -> PHASE_IDLE                */
2308         acornscsi_done(host, &host->SCpnt, DID_OK);
2309         return INTR_NEXT_COMMAND;
2310 
2311     case 0x1e:
2312     case 0x8e:
2313         acornscsi_sendmessage(host);
2314         break;
2315 
2316     default:
2317         printk(KERN_ERR "scsi%d.%c: PHASE_DONE, SSR %02X instead of disconnect?\n",
2318             host->host->host_no, acornscsi_target(host), ssr);
2319         acornscsi_dumplog(host, host->SCpnt ? host->SCpnt->device->id : 8);
2320     }
2321     return INTR_PROCESSING;
2322 
2323     case PHASE_ABORTED:
2324     switch (ssr) {
2325     case 0x85:
2326         if (host->SCpnt)
2327         acornscsi_done(host, &host->SCpnt, DID_ABORT);
2328         else {
2329         clear_bit(host->scsi.reconnected.target * 8 + host->scsi.reconnected.lun,
2330               host->busyluns);
2331         host->scsi.phase = PHASE_IDLE;
2332         }
2333         return INTR_NEXT_COMMAND;
2334 
2335     case 0x1e:
2336     case 0x2e:
2337     case 0x4e:
2338     case 0x8e:
2339         acornscsi_sendmessage(host);
2340         break;
2341 
2342     default:
2343         printk(KERN_ERR "scsi%d.%c: PHASE_ABORTED, SSR %02X?\n",
2344             host->host->host_no, acornscsi_target(host), ssr);
2345         acornscsi_dumplog(host, host->SCpnt ? host->SCpnt->device->id : 8);
2346     }
2347     return INTR_PROCESSING;
2348 
2349     default:
2350     printk(KERN_ERR "scsi%d.%c: unknown driver phase %d\n",
2351         host->host->host_no, acornscsi_target(host), ssr);
2352     acornscsi_dumplog(host, host->SCpnt ? host->SCpnt->device->id : 8);
2353     }
2354     return INTR_PROCESSING;
2355 }
2356 
2357 /*
2358  * Prototype: void acornscsi_intr(int irq, void *dev_id)
2359  * Purpose  : handle interrupts from Acorn SCSI card
2360  * Params   : irq    - interrupt number
2361  *        dev_id - device specific data (AS_Host structure)
2362  */
2363 static irqreturn_t
2364 acornscsi_intr(int irq, void *dev_id)
2365 {
2366     AS_Host *host = (AS_Host *)dev_id;
2367     intr_ret_t ret;
2368     int iostatus;
2369     int in_irq = 0;
2370 
2371     do {
2372     ret = INTR_IDLE;
2373 
2374     iostatus = readb(host->fast + INT_REG);
2375 
2376     if (iostatus & 2) {
2377         acornscsi_dma_intr(host);
2378         iostatus = readb(host->fast + INT_REG);
2379     }
2380 
2381     if (iostatus & 8)
2382         ret = acornscsi_sbicintr(host, in_irq);
2383 
2384     /*
2385      * If we have a transfer pending, start it.
2386      * Only start it if the interface has already started transferring
2387      * it's data
2388      */
2389     if (host->dma.xfer_required)
2390         acornscsi_dma_xfer(host);
2391 
2392     if (ret == INTR_NEXT_COMMAND)
2393         ret = acornscsi_kick(host);
2394 
2395     in_irq = 1;
2396     } while (ret != INTR_IDLE);
2397 
2398     return IRQ_HANDLED;
2399 }
2400 
2401 /*=============================================================================================
2402  * Interfaces between interrupt handler and rest of scsi code
2403  */
2404 
2405 /*
2406  * Function : acornscsi_queuecmd(struct scsi_cmnd *cmd)
2407  * Purpose  : queues a SCSI command
2408  * Params   : cmd  - SCSI command
2409  * Returns  : 0, or < 0 on error.
2410  */
2411 static int acornscsi_queuecmd_lck(struct scsi_cmnd *SCpnt)
2412 {
2413     struct scsi_pointer *scsi_pointer = arm_scsi_pointer(SCpnt);
2414     void (*done)(struct scsi_cmnd *) = scsi_done;
2415     AS_Host *host = (AS_Host *)SCpnt->device->host->hostdata;
2416 
2417 #if (DEBUG & DEBUG_NO_WRITE)
2418     if (acornscsi_cmdtype(SCpnt->cmnd[0]) == CMD_WRITE && (NO_WRITE & (1 << SCpnt->device->id))) {
2419     printk(KERN_CRIT "scsi%d.%c: WRITE attempted with NO_WRITE flag set\n",
2420         host->host->host_no, '0' + SCpnt->device->id);
2421     set_host_byte(SCpnt, DID_NO_CONNECT);
2422     done(SCpnt);
2423     return 0;
2424     }
2425 #endif
2426 
2427     SCpnt->host_scribble = NULL;
2428     SCpnt->result = 0;
2429     scsi_pointer->phase = (int)acornscsi_datadirection(SCpnt->cmnd[0]);
2430     scsi_pointer->sent_command = 0;
2431     scsi_pointer->scsi_xferred = 0;
2432 
2433     init_SCp(SCpnt);
2434 
2435     host->stats.queues += 1;
2436 
2437     {
2438     unsigned long flags;
2439 
2440     if (!queue_add_cmd_ordered(&host->queues.issue, SCpnt)) {
2441         set_host_byte(SCpnt, DID_ERROR);
2442         done(SCpnt);
2443         return 0;
2444     }
2445     local_irq_save(flags);
2446     if (host->scsi.phase == PHASE_IDLE)
2447         acornscsi_kick(host);
2448     local_irq_restore(flags);
2449     }
2450     return 0;
2451 }
2452 
2453 DEF_SCSI_QCMD(acornscsi_queuecmd)
2454 
2455 enum res_abort { res_not_running, res_success, res_success_clear, res_snooze };
2456 
2457 /*
2458  * Prototype: enum res acornscsi_do_abort(struct scsi_cmnd *SCpnt)
2459  * Purpose  : abort a command on this host
2460  * Params   : SCpnt - command to abort
2461  * Returns  : our abort status
2462  */
2463 static enum res_abort acornscsi_do_abort(AS_Host *host, struct scsi_cmnd *SCpnt)
2464 {
2465     enum res_abort res = res_not_running;
2466 
2467     if (queue_remove_cmd(&host->queues.issue, SCpnt)) {
2468         /*
2469          * The command was on the issue queue, and has not been
2470          * issued yet.  We can remove the command from the queue,
2471          * and acknowledge the abort.  Neither the devices nor the
2472          * interface know about the command.
2473          */
2474 //#if (DEBUG & DEBUG_ABORT)
2475         printk("on issue queue ");
2476 //#endif
2477         res = res_success;
2478     } else if (queue_remove_cmd(&host->queues.disconnected, SCpnt)) {
2479         /*
2480          * The command was on the disconnected queue.  Simply
2481          * acknowledge the abort condition, and when the target
2482          * reconnects, we will give it an ABORT message.  The
2483          * target should then disconnect, and we will clear
2484          * the busylun bit.
2485          */
2486 //#if (DEBUG & DEBUG_ABORT)
2487         printk("on disconnected queue ");
2488 //#endif
2489         res = res_success;
2490     } else if (host->SCpnt == SCpnt) {
2491         unsigned long flags;
2492 
2493 //#if (DEBUG & DEBUG_ABORT)
2494         printk("executing ");
2495 //#endif
2496 
2497         local_irq_save(flags);
2498         switch (host->scsi.phase) {
2499         /*
2500          * If the interface is idle, and the command is 'disconnectable',
2501          * then it is the same as on the disconnected queue.  We simply
2502          * remove all traces of the command.  When the target reconnects,
2503          * we will give it an ABORT message since the command could not
2504          * be found.  When the target finally disconnects, we will clear
2505          * the busylun bit.
2506          */
2507         case PHASE_IDLE:
2508             if (host->scsi.disconnectable) {
2509                 host->scsi.disconnectable = 0;
2510                 host->SCpnt = NULL;
2511                 res = res_success;
2512             }
2513             break;
2514 
2515         /*
2516          * If the command has connected and done nothing further,
2517          * simply force a disconnect.  We also need to clear the
2518          * busylun bit.
2519          */
2520         case PHASE_CONNECTED:
2521             sbic_arm_write(host, SBIC_CMND, CMND_DISCONNECT);
2522             host->SCpnt = NULL;
2523             res = res_success_clear;
2524             break;
2525 
2526         default:
2527             acornscsi_abortcmd(host);
2528             res = res_snooze;
2529         }
2530         local_irq_restore(flags);
2531     } else if (host->origSCpnt == SCpnt) {
2532         /*
2533          * The command will be executed next, but a command
2534          * is currently using the interface.  This is similar to
2535          * being on the issue queue, except the busylun bit has
2536          * been set.
2537          */
2538         host->origSCpnt = NULL;
2539 //#if (DEBUG & DEBUG_ABORT)
2540         printk("waiting for execution ");
2541 //#endif
2542         res = res_success_clear;
2543     } else
2544         printk("unknown ");
2545 
2546     return res;
2547 }
2548 
2549 /*
2550  * Prototype: int acornscsi_abort(struct scsi_cmnd *SCpnt)
2551  * Purpose  : abort a command on this host
2552  * Params   : SCpnt - command to abort
2553  * Returns  : one of SCSI_ABORT_ macros
2554  */
2555 int acornscsi_abort(struct scsi_cmnd *SCpnt)
2556 {
2557     AS_Host *host = (AS_Host *) SCpnt->device->host->hostdata;
2558     int result;
2559 
2560     host->stats.aborts += 1;
2561 
2562 #if (DEBUG & DEBUG_ABORT)
2563     {
2564         int asr, ssr;
2565         asr = sbic_arm_read(host, SBIC_ASR);
2566         ssr = sbic_arm_read(host, SBIC_SSR);
2567 
2568         printk(KERN_WARNING "acornscsi_abort: ");
2569         print_sbic_status(asr, ssr, host->scsi.phase);
2570         acornscsi_dumplog(host, SCpnt->device->id);
2571     }
2572 #endif
2573 
2574     printk("scsi%d: ", host->host->host_no);
2575 
2576     switch (acornscsi_do_abort(host, SCpnt)) {
2577     /*
2578      * We managed to find the command and cleared it out.
2579      * We do not expect the command to be executing on the
2580      * target, but we have set the busylun bit.
2581      */
2582     case res_success_clear:
2583 //#if (DEBUG & DEBUG_ABORT)
2584         printk("clear ");
2585 //#endif
2586         clear_bit(SCpnt->device->id * 8 +
2587               (u8)(SCpnt->device->lun & 0x7), host->busyluns);
2588         fallthrough;
2589 
2590     /*
2591      * We found the command, and cleared it out.  Either
2592      * the command is still known to be executing on the
2593      * target, or the busylun bit is not set.
2594      */
2595     case res_success:
2596 //#if (DEBUG & DEBUG_ABORT)
2597         printk("success\n");
2598 //#endif
2599         result = SUCCESS;
2600         break;
2601 
2602     /*
2603      * We did find the command, but unfortunately we couldn't
2604      * unhook it from ourselves.  Wait some more, and if it
2605      * still doesn't complete, reset the interface.
2606      */
2607     case res_snooze:
2608 //#if (DEBUG & DEBUG_ABORT)
2609         printk("snooze\n");
2610 //#endif
2611         result = FAILED;
2612         break;
2613 
2614     /*
2615      * The command could not be found (either because it completed,
2616      * or it got dropped.
2617      */
2618     default:
2619     case res_not_running:
2620         acornscsi_dumplog(host, SCpnt->device->id);
2621         result = FAILED;
2622 //#if (DEBUG & DEBUG_ABORT)
2623         printk("not running\n");
2624 //#endif
2625         break;
2626     }
2627 
2628     return result;
2629 }
2630 
2631 /*
2632  * Prototype: int acornscsi_reset(struct scsi_cmnd *SCpnt)
2633  * Purpose  : reset a command on this host/reset this host
2634  * Params   : SCpnt  - command causing reset
2635  * Returns  : one of SCSI_RESET_ macros
2636  */
2637 int acornscsi_host_reset(struct scsi_cmnd *SCpnt)
2638 {
2639     AS_Host *host = (AS_Host *)SCpnt->device->host->hostdata;
2640     struct scsi_cmnd *SCptr;
2641     
2642     host->stats.resets += 1;
2643 
2644 #if (DEBUG & DEBUG_RESET)
2645     {
2646     int asr, ssr, devidx;
2647 
2648     asr = sbic_arm_read(host, SBIC_ASR);
2649     ssr = sbic_arm_read(host, SBIC_SSR);
2650 
2651     printk(KERN_WARNING "acornscsi_reset: ");
2652     print_sbic_status(asr, ssr, host->scsi.phase);
2653     for (devidx = 0; devidx < 9; devidx++)
2654         acornscsi_dumplog(host, devidx);
2655     }
2656 #endif
2657 
2658     acornscsi_dma_stop(host);
2659 
2660     /*
2661      * do hard reset.  This resets all devices on this host, and so we
2662      * must set the reset status on all commands.
2663      */
2664     acornscsi_resetcard(host);
2665 
2666     while ((SCptr = queue_remove(&host->queues.disconnected)) != NULL)
2667     ;
2668 
2669     return SUCCESS;
2670 }
2671 
2672 /*==============================================================================================
2673  * initialisation & miscellaneous support
2674  */
2675 
2676 /*
2677  * Function: char *acornscsi_info(struct Scsi_Host *host)
2678  * Purpose : return a string describing this interface
2679  * Params  : host - host to give information on
2680  * Returns : a constant string
2681  */
2682 const
2683 char *acornscsi_info(struct Scsi_Host *host)
2684 {
2685     static char string[100], *p;
2686 
2687     p = string;
2688     
2689     p += sprintf(string, "%s at port %08lX irq %d v%d.%d.%d"
2690 #ifdef CONFIG_SCSI_ACORNSCSI_SYNC
2691     " SYNC"
2692 #endif
2693 #if (DEBUG & DEBUG_NO_WRITE)
2694     " NOWRITE (" __stringify(NO_WRITE) ")"
2695 #endif
2696         , host->hostt->name, host->io_port, host->irq,
2697         VER_MAJOR, VER_MINOR, VER_PATCH);
2698     return string;
2699 }
2700 
2701 static int acornscsi_show_info(struct seq_file *m, struct Scsi_Host *instance)
2702 {
2703     int devidx;
2704     struct scsi_device *scd;
2705     AS_Host *host;
2706 
2707     host  = (AS_Host *)instance->hostdata;
2708     
2709     seq_printf(m, "AcornSCSI driver v%d.%d.%d"
2710 #ifdef CONFIG_SCSI_ACORNSCSI_SYNC
2711     " SYNC"
2712 #endif
2713 #if (DEBUG & DEBUG_NO_WRITE)
2714     " NOWRITE (" __stringify(NO_WRITE) ")"
2715 #endif
2716         "\n\n", VER_MAJOR, VER_MINOR, VER_PATCH);
2717 
2718     seq_printf(m,   "SBIC: WD33C93A  Address: %p    IRQ : %d\n",
2719             host->base + SBIC_REGIDX, host->scsi.irq);
2720 #ifdef USE_DMAC
2721     seq_printf(m,   "DMAC: uPC71071  Address: %p  IRQ : %d\n\n",
2722             host->base + DMAC_OFFSET, host->scsi.irq);
2723 #endif
2724 
2725     seq_printf(m,   "Statistics:\n"
2726             "Queued commands: %-10u    Issued commands: %-10u\n"
2727             "Done commands  : %-10u    Reads          : %-10u\n"
2728             "Writes         : %-10u    Others         : %-10u\n"
2729             "Disconnects    : %-10u    Aborts         : %-10u\n"
2730             "Resets         : %-10u\n\nLast phases:",
2731             host->stats.queues,     host->stats.removes,
2732             host->stats.fins,       host->stats.reads,
2733             host->stats.writes,     host->stats.miscs,
2734             host->stats.disconnects,    host->stats.aborts,
2735             host->stats.resets);
2736 
2737     for (devidx = 0; devidx < 9; devidx ++) {
2738     unsigned int statptr, prev;
2739 
2740     seq_printf(m, "\n%c:", devidx == 8 ? 'H' : ('0' + devidx));
2741     statptr = host->status_ptr[devidx] - 10;
2742 
2743     if ((signed int)statptr < 0)
2744         statptr += STATUS_BUFFER_SIZE;
2745 
2746     prev = host->status[devidx][statptr].when;
2747 
2748     for (; statptr != host->status_ptr[devidx]; statptr = (statptr + 1) & (STATUS_BUFFER_SIZE - 1)) {
2749         if (host->status[devidx][statptr].when) {
2750         seq_printf(m, "%c%02X:%02X+%2ld",
2751             host->status[devidx][statptr].irq ? '-' : ' ',
2752             host->status[devidx][statptr].ph,
2753             host->status[devidx][statptr].ssr,
2754             (host->status[devidx][statptr].when - prev) < 100 ?
2755                 (host->status[devidx][statptr].when - prev) : 99);
2756         prev = host->status[devidx][statptr].when;
2757         }
2758     }
2759     }
2760 
2761     seq_printf(m, "\nAttached devices:\n");
2762 
2763     shost_for_each_device(scd, instance) {
2764     seq_printf(m, "Device/Lun TaggedQ      Sync\n");
2765     seq_printf(m, "     %d/%llu   ", scd->id, scd->lun);
2766     if (scd->tagged_supported)
2767         seq_printf(m, "%3sabled ",
2768                  scd->simple_tags ? "en" : "dis");
2769     else
2770         seq_printf(m, "unsupported  ");
2771 
2772     if (host->device[scd->id].sync_xfer & 15)
2773         seq_printf(m, "offset %d, %d ns\n",
2774                  host->device[scd->id].sync_xfer & 15,
2775                  acornscsi_getperiod(host->device[scd->id].sync_xfer));
2776     else
2777         seq_printf(m, "async\n");
2778 
2779     }
2780     return 0;
2781 }
2782 
2783 static struct scsi_host_template acornscsi_template = {
2784     .module         = THIS_MODULE,
2785     .show_info      = acornscsi_show_info,
2786     .name           = "AcornSCSI",
2787     .info           = acornscsi_info,
2788     .queuecommand       = acornscsi_queuecmd,
2789     .eh_abort_handler   = acornscsi_abort,
2790     .eh_host_reset_handler  = acornscsi_host_reset,
2791     .can_queue      = 16,
2792     .this_id        = 7,
2793     .sg_tablesize       = SG_ALL,
2794     .cmd_per_lun        = 2,
2795     .dma_boundary       = PAGE_SIZE - 1,
2796     .proc_name      = "acornscsi",
2797     .cmd_size       = sizeof(struct arm_cmd_priv),
2798 };
2799 
2800 static int acornscsi_probe(struct expansion_card *ec, const struct ecard_id *id)
2801 {
2802     struct Scsi_Host *host;
2803     AS_Host *ashost;
2804     int ret;
2805 
2806     ret = ecard_request_resources(ec);
2807     if (ret)
2808         goto out;
2809 
2810     host = scsi_host_alloc(&acornscsi_template, sizeof(AS_Host));
2811     if (!host) {
2812         ret = -ENOMEM;
2813         goto out_release;
2814     }
2815 
2816     ashost = (AS_Host *)host->hostdata;
2817 
2818     ashost->base = ecardm_iomap(ec, ECARD_RES_MEMC, 0, 0);
2819     ashost->fast = ecardm_iomap(ec, ECARD_RES_IOCFAST, 0, 0);
2820     if (!ashost->base || !ashost->fast) {
2821         ret = -ENOMEM;
2822         goto out_put;
2823     }
2824 
2825     host->irq = ec->irq;
2826     ashost->host = host;
2827     ashost->scsi.irq = host->irq;
2828 
2829     ec->irqaddr = ashost->fast + INT_REG;
2830     ec->irqmask = 0x0a;
2831 
2832     ret = request_irq(host->irq, acornscsi_intr, 0, "acornscsi", ashost);
2833     if (ret) {
2834         printk(KERN_CRIT "scsi%d: IRQ%d not free: %d\n",
2835             host->host_no, ashost->scsi.irq, ret);
2836         goto out_put;
2837     }
2838 
2839     memset(&ashost->stats, 0, sizeof (ashost->stats));
2840     queue_initialise(&ashost->queues.issue);
2841     queue_initialise(&ashost->queues.disconnected);
2842     msgqueue_initialise(&ashost->scsi.msgs);
2843 
2844     acornscsi_resetcard(ashost);
2845 
2846     ret = scsi_add_host(host, &ec->dev);
2847     if (ret)
2848         goto out_irq;
2849 
2850     scsi_scan_host(host);
2851     goto out;
2852 
2853  out_irq:
2854     free_irq(host->irq, ashost);
2855     msgqueue_free(&ashost->scsi.msgs);
2856     queue_free(&ashost->queues.disconnected);
2857     queue_free(&ashost->queues.issue);
2858  out_put:
2859     ecardm_iounmap(ec, ashost->fast);
2860     ecardm_iounmap(ec, ashost->base);
2861     scsi_host_put(host);
2862  out_release:
2863     ecard_release_resources(ec);
2864  out:
2865     return ret;
2866 }
2867 
2868 static void acornscsi_remove(struct expansion_card *ec)
2869 {
2870     struct Scsi_Host *host = ecard_get_drvdata(ec);
2871     AS_Host *ashost = (AS_Host *)host->hostdata;
2872 
2873     ecard_set_drvdata(ec, NULL);
2874     scsi_remove_host(host);
2875 
2876     /*
2877      * Put card into RESET state
2878      */
2879     writeb(0x80, ashost->fast + PAGE_REG);
2880 
2881     free_irq(host->irq, ashost);
2882 
2883     msgqueue_free(&ashost->scsi.msgs);
2884     queue_free(&ashost->queues.disconnected);
2885     queue_free(&ashost->queues.issue);
2886     ecardm_iounmap(ec, ashost->fast);
2887     ecardm_iounmap(ec, ashost->base);
2888     scsi_host_put(host);
2889     ecard_release_resources(ec);
2890 }
2891 
2892 static const struct ecard_id acornscsi_cids[] = {
2893     { MANU_ACORN, PROD_ACORN_SCSI },
2894     { 0xffff, 0xffff },
2895 };
2896 
2897 static struct ecard_driver acornscsi_driver = {
2898     .probe      = acornscsi_probe,
2899     .remove     = acornscsi_remove,
2900     .id_table   = acornscsi_cids,
2901     .drv = {
2902         .name       = "acornscsi",
2903     },
2904 };
2905 
2906 static int __init acornscsi_init(void)
2907 {
2908     return ecard_register_driver(&acornscsi_driver);
2909 }
2910 
2911 static void __exit acornscsi_exit(void)
2912 {
2913     ecard_remove_driver(&acornscsi_driver);
2914 }
2915 
2916 module_init(acornscsi_init);
2917 module_exit(acornscsi_exit);
2918 
2919 MODULE_AUTHOR("Russell King");
2920 MODULE_DESCRIPTION("AcornSCSI driver");
2921 MODULE_LICENSE("GPL");