1 // SPDX-License-Identifier: GPL-2.0-only
3 * linux/drivers/acorn/scsi/acornscsi.c
8 * Abandoned using the Select and Transfer command since there were
9 * some nasty races between our software and the target devices that
10 * were not easy to solve, and the device errata had a lot of entries
11 * for this command, some of them quite nasty...
14 * 26-Sep-1997 RMK Re-jigged to use the queue module.
15 * Re-coded state machine to be based on driver
16 * state not scsi state. Should be easier to debug.
17 * Added acornscsi_release to clean up properly.
18 * Updated proc/scsi reporting.
19 * 05-Oct-1997 RMK Implemented writing to SCSI devices.
20 * 06-Oct-1997 RMK Corrected small (non-serious) bug with the connect/
21 * reconnect race condition causing a warning message.
22 * 12-Oct-1997 RMK Added catch for re-entering interrupt routine.
23 * 15-Oct-1997 RMK Improved handling of commands.
24 * 27-Jun-1998 RMK Changed asm/delay.h to linux/delay.h.
25 * 13-Dec-1998 RMK Better abort code and command handling. Extra state
26 * transitions added to allow dodgy devices to work.
28 #define DEBUG_NO_WRITE 1
29 #define DEBUG_QUEUES 2
32 #define DEBUG_DISCON 16
33 #define DEBUG_CONNECT 32
34 #define DEBUG_PHASES 64
35 #define DEBUG_WRITE 128
36 #define DEBUG_LINK 256
37 #define DEBUG_MESSAGES 512
38 #define DEBUG_RESET 1024
39 #define DEBUG_ALL (DEBUG_RESET|DEBUG_MESSAGES|DEBUG_LINK|DEBUG_WRITE|\
40 DEBUG_PHASES|DEBUG_CONNECT|DEBUG_DISCON|DEBUG_ABORT|\
41 DEBUG_DMA|DEBUG_QUEUES)
43 /* DRIVER CONFIGURATION
45 * SCSI-II Tagged queue support.
47 * I don't have any SCSI devices that support it, so it is totally untested
48 * (except to make sure that it doesn't interfere with any non-tagging
49 * devices). It is not fully implemented either - what happens when a
50 * tagging device reconnects???
52 * You can tell if you have a device that supports tagged queueing my
53 * cating (eg) /proc/scsi/acornscsi/0 and see if the SCSI revision is reported
58 * SCSI-II Synchronous transfer support.
62 * SDTR_SIZE - maximum number of un-acknowledged bytes (0 = off, 12 = max)
63 * SDTR_PERIOD - period of REQ signal (min=125, max=1020)
64 * DEFAULT_PERIOD - default REQ period.
67 #define SDTR_PERIOD 125
68 #define DEFAULT_PERIOD 500
71 * Debugging information
73 * DEBUG - bit mask from list above
74 * DEBUG_TARGET - is defined to the target number if you want to debug
75 * a specific target. [only recon/write/dma].
77 #define DEBUG (DEBUG_RESET|DEBUG_WRITE|DEBUG_NO_WRITE)
78 /* only allow writing to SCSI device 0 */
80 /*#define DEBUG_TARGET 2*/
82 * Select timeout time (in 10ms units)
84 * This is the timeout used between the start of selection and the WD33C93
85 * chip deciding that the device isn't responding.
87 #define TIMEOUT_TIME 10
89 * Define this if you want to have verbose explanation of SCSI
92 #undef CONFIG_ACORNSCSI_CONSTANTS
94 * Define this if you want to use the on board DMAC [don't remove this option]
95 * If not set, then use PIO mode (not currently supported).
100 * ====================================================================================
104 #define DBG(cmd,xxx...) \
105 if (cmd->device->id == DEBUG_TARGET) { \
109 #define DBG(cmd,xxx...) xxx
112 #include <linux/module.h>
113 #include <linux/kernel.h>
114 #include <linux/string.h>
115 #include <linux/signal.h>
116 #include <linux/errno.h>
117 #include <linux/proc_fs.h>
118 #include <linux/ioport.h>
119 #include <linux/blkdev.h>
120 #include <linux/delay.h>
121 #include <linux/interrupt.h>
122 #include <linux/init.h>
123 #include <linux/bitops.h>
124 #include <linux/stringify.h>
125 #include <linux/io.h>
127 #include <asm/ecard.h>
129 #include <scsi/scsi.h>
130 #include <scsi/scsi_cmnd.h>
131 #include <scsi/scsi_dbg.h>
132 #include <scsi/scsi_device.h>
133 #include <scsi/scsi_eh.h>
134 #include <scsi/scsi_host.h>
135 #include <scsi/scsi_tcq.h>
136 #include <scsi/scsi_transport_spi.h>
137 #include "acornscsi.h"
138 #include "msgqueue.h"
139 #include "arm_scsi.h"
141 #include <scsi/scsicam.h>
149 * DMAC setup parameters
151 #define INIT_DEVCON0 (DEVCON0_RQL|DEVCON0_EXW|DEVCON0_CMP)
152 #define INIT_DEVCON1 (DEVCON1_BHLD)
153 #define DMAC_READ (MODECON_READ)
154 #define DMAC_WRITE (MODECON_WRITE)
155 #define INIT_SBICDMA (CTRL_DMABURST)
157 #define scsi_xferred have_data_in
160 * Size of on-board DMA buffer
162 #define DMAC_BUFFER_SIZE 65536
165 #define STATUS_BUFFER_TO_PRINT 24
167 unsigned int sdtr_period
= SDTR_PERIOD
;
168 unsigned int sdtr_size
= SDTR_SIZE
;
170 static void acornscsi_done(AS_Host
*host
, struct scsi_cmnd
**SCpntp
,
171 unsigned int result
);
172 static int acornscsi_reconnect_finish(AS_Host
*host
);
173 static void acornscsi_dma_cleanup(AS_Host
*host
);
174 static void acornscsi_abortcmd(AS_Host
*host
);
176 /* ====================================================================================
180 /* Offsets from MEMC base */
181 #define SBIC_REGIDX 0x2000
182 #define SBIC_REGVAL 0x2004
183 #define DMAC_OFFSET 0x3000
185 /* Offsets from FAST IOC base */
186 #define INT_REG 0x2000
187 #define PAGE_REG 0x3000
189 static inline void sbic_arm_write(AS_Host
*host
, unsigned int reg
, unsigned int value
)
191 writeb(reg
, host
->base
+ SBIC_REGIDX
);
192 writeb(value
, host
->base
+ SBIC_REGVAL
);
195 static inline int sbic_arm_read(AS_Host
*host
, unsigned int reg
)
198 return readl(host
->base
+ SBIC_REGIDX
) & 255;
199 writeb(reg
, host
->base
+ SBIC_REGIDX
);
200 return readl(host
->base
+ SBIC_REGVAL
) & 255;
203 #define sbic_arm_writenext(host, val) writeb((val), (host)->base + SBIC_REGVAL)
204 #define sbic_arm_readnext(host) readb((host)->base + SBIC_REGVAL)
207 #define dmac_read(host,reg) \
208 readb((host)->base + DMAC_OFFSET + ((reg) << 2))
210 #define dmac_write(host,reg,value) \
211 ({ writeb((value), (host)->base + DMAC_OFFSET + ((reg) << 2)); })
213 #define dmac_clearintr(host) writeb(0, (host)->fast + INT_REG)
215 static inline unsigned int dmac_address(AS_Host
*host
)
217 return dmac_read(host
, DMAC_TXADRHI
) << 16 |
218 dmac_read(host
, DMAC_TXADRMD
) << 8 |
219 dmac_read(host
, DMAC_TXADRLO
);
223 void acornscsi_dumpdma(AS_Host
*host
, char *where
)
225 unsigned int mode
, addr
, len
;
227 mode
= dmac_read(host
, DMAC_MODECON
);
228 addr
= dmac_address(host
);
229 len
= dmac_read(host
, DMAC_TXCNTHI
) << 8 |
230 dmac_read(host
, DMAC_TXCNTLO
);
232 printk("scsi%d: %s: DMAC %02x @%06x+%04x msk %02x, ",
233 host
->host
->host_no
, where
,
234 mode
, addr
, (len
+ 1) & 0xffff,
235 dmac_read(host
, DMAC_MASKREG
));
237 printk("DMA @%06x, ", host
->dma
.start_addr
);
238 printk("BH @%p +%04x, ", host
->scsi
.SCp
.ptr
,
239 host
->scsi
.SCp
.this_residual
);
240 printk("DT @+%04x ST @+%04x", host
->dma
.transferred
,
241 host
->scsi
.SCp
.scsi_xferred
);
247 unsigned long acornscsi_sbic_xfcount(AS_Host
*host
)
249 unsigned long length
;
251 length
= sbic_arm_read(host
, SBIC_TRANSCNTH
) << 16;
252 length
|= sbic_arm_readnext(host
) << 8;
253 length
|= sbic_arm_readnext(host
);
259 acornscsi_sbic_wait(AS_Host
*host
, int stat_mask
, int stat
, int timeout
, char *msg
)
264 asr
= sbic_arm_read(host
, SBIC_ASR
);
266 if ((asr
& stat_mask
) == stat
)
272 printk("scsi%d: timeout while %s\n", host
->host
->host_no
, msg
);
278 int acornscsi_sbic_issuecmd(AS_Host
*host
, int command
)
280 if (acornscsi_sbic_wait(host
, ASR_CIP
, 0, 1000, "issuing command"))
283 sbic_arm_write(host
, SBIC_CMND
, command
);
289 acornscsi_csdelay(unsigned int cs
)
291 unsigned long target_jiffies
, flags
;
293 target_jiffies
= jiffies
+ 1 + cs
* HZ
/ 100;
295 local_save_flags(flags
);
298 while (time_before(jiffies
, target_jiffies
)) barrier();
300 local_irq_restore(flags
);
304 void acornscsi_resetcard(AS_Host
*host
)
306 unsigned int i
, timeout
;
308 /* assert reset line */
309 host
->card
.page_reg
= 0x80;
310 writeb(host
->card
.page_reg
, host
->fast
+ PAGE_REG
);
312 /* wait 3 cs. SCSI standard says 25ms. */
313 acornscsi_csdelay(3);
315 host
->card
.page_reg
= 0;
316 writeb(host
->card
.page_reg
, host
->fast
+ PAGE_REG
);
319 * Should get a reset from the card
323 if (readb(host
->fast
+ INT_REG
) & 8)
329 printk("scsi%d: timeout while resetting card\n",
330 host
->host
->host_no
);
332 sbic_arm_read(host
, SBIC_ASR
);
333 sbic_arm_read(host
, SBIC_SSR
);
335 /* setup sbic - WD33C93A */
336 sbic_arm_write(host
, SBIC_OWNID
, OWNID_EAF
| host
->host
->this_id
);
337 sbic_arm_write(host
, SBIC_CMND
, CMND_RESET
);
340 * Command should cause a reset interrupt
344 if (readb(host
->fast
+ INT_REG
) & 8)
350 printk("scsi%d: timeout while resetting card\n",
351 host
->host
->host_no
);
353 sbic_arm_read(host
, SBIC_ASR
);
354 if (sbic_arm_read(host
, SBIC_SSR
) != 0x01)
355 printk(KERN_CRIT
"scsi%d: WD33C93A didn't give enhanced reset interrupt\n",
356 host
->host
->host_no
);
358 sbic_arm_write(host
, SBIC_CTRL
, INIT_SBICDMA
| CTRL_IDI
);
359 sbic_arm_write(host
, SBIC_TIMEOUT
, TIMEOUT_TIME
);
360 sbic_arm_write(host
, SBIC_SYNCHTRANSFER
, SYNCHTRANSFER_2DBA
);
361 sbic_arm_write(host
, SBIC_SOURCEID
, SOURCEID_ER
| SOURCEID_DSP
);
363 host
->card
.page_reg
= 0x40;
364 writeb(host
->card
.page_reg
, host
->fast
+ PAGE_REG
);
366 /* setup dmac - uPC71071 */
367 dmac_write(host
, DMAC_INIT
, 0);
369 dmac_write(host
, DMAC_INIT
, INIT_8BIT
);
370 dmac_write(host
, DMAC_CHANNEL
, CHANNEL_0
);
371 dmac_write(host
, DMAC_DEVCON0
, INIT_DEVCON0
);
372 dmac_write(host
, DMAC_DEVCON1
, INIT_DEVCON1
);
376 host
->scsi
.phase
= PHASE_IDLE
;
377 host
->scsi
.disconnectable
= 0;
379 memset(host
->busyluns
, 0, sizeof(host
->busyluns
));
381 for (i
= 0; i
< 8; i
++) {
382 host
->device
[i
].sync_state
= SYNC_NEGOCIATE
;
383 host
->device
[i
].disconnect_ok
= 1;
386 /* wait 25 cs. SCSI standard says 250ms. */
387 acornscsi_csdelay(25);
390 /*=============================================================================================
391 * Utility routines (eg. debug)
393 #ifdef CONFIG_ACORNSCSI_CONSTANTS
394 static char *acornscsi_interrupttype
[] = {
395 "rst", "suc", "p/a", "3",
396 "term", "5", "6", "7",
397 "serv", "9", "a", "b",
401 static signed char acornscsi_map
[] = {
402 0, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
403 -1, 2, -1, -1, -1, -1, 3, -1, 4, 5, 6, 7, 8, 9, 10, 11,
404 12, 13, 14, -1, -1, -1, -1, -1, 4, 5, 6, 7, 8, 9, 10, 11,
405 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
406 15, 16, 17, 18, 19, -1, -1, 20, 4, 5, 6, 7, 8, 9, 10, 11,
407 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
408 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
409 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
410 21, 22, -1, -1, -1, 23, -1, -1, 4, 5, 6, 7, 8, 9, 10, 11,
411 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
412 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
413 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
414 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
415 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
416 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
417 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
420 static char *acornscsi_interruptcode
[] = {
422 "reset - normal mode", /* 00 */
423 "reset - advanced mode", /* 01 */
438 "/ACK asserted", /* 20 */
439 "save-data-ptr", /* 21 */
444 "unexpected disconnect", /* 41 */
445 "sel timeout", /* 42 */
447 "P err+ATN", /* 44 */
448 "bad status byte", /* 47 */
451 "resel, no id", /* 80 */
457 void print_scsi_status(unsigned int ssr
)
459 if (acornscsi_map
[ssr
] != -1)
461 acornscsi_interrupttype
[(ssr
>> 4)],
462 acornscsi_interruptcode
[acornscsi_map
[ssr
]]);
464 printk("%X:%X", ssr
>> 4, ssr
& 0x0f);
469 void print_sbic_status(int asr
, int ssr
, int cmdphase
)
471 #ifdef CONFIG_ACORNSCSI_CONSTANTS
472 printk("sbic: %c%c%c%c%c%c ",
473 asr
& ASR_INT
? 'I' : 'i',
474 asr
& ASR_LCI
? 'L' : 'l',
475 asr
& ASR_BSY
? 'B' : 'b',
476 asr
& ASR_CIP
? 'C' : 'c',
477 asr
& ASR_PE
? 'P' : 'p',
478 asr
& ASR_DBR
? 'D' : 'd');
480 print_scsi_status(ssr
);
481 printk(" ph %02X\n", cmdphase
);
483 printk("sbic: %02X scsi: %X:%X ph: %02X\n",
484 asr
, (ssr
& 0xf0)>>4, ssr
& 0x0f, cmdphase
);
489 acornscsi_dumplogline(AS_Host
*host
, int target
, int line
)
494 ptr
= host
->status_ptr
[target
] - STATUS_BUFFER_TO_PRINT
;
496 ptr
+= STATUS_BUFFER_SIZE
;
498 printk("%c: %3s:", target
== 8 ? 'H' : '0' + target
,
499 line
== 0 ? "ph" : line
== 1 ? "ssr" : "int");
501 prev
= host
->status
[target
][ptr
].when
;
503 for (; ptr
!= host
->status_ptr
[target
]; ptr
= (ptr
+ 1) & (STATUS_BUFFER_SIZE
- 1)) {
504 unsigned long time_diff
;
506 if (!host
->status
[target
][ptr
].when
)
511 printk("%c%02X", host
->status
[target
][ptr
].irq
? '-' : ' ',
512 host
->status
[target
][ptr
].ph
);
516 printk(" %02X", host
->status
[target
][ptr
].ssr
);
520 time_diff
= host
->status
[target
][ptr
].when
- prev
;
521 prev
= host
->status
[target
][ptr
].when
;
524 else if (time_diff
>= 100)
527 printk(" %02ld", time_diff
);
536 void acornscsi_dumplog(AS_Host
*host
, int target
)
539 acornscsi_dumplogline(host
, target
, 0);
540 acornscsi_dumplogline(host
, target
, 1);
541 acornscsi_dumplogline(host
, target
, 2);
551 char acornscsi_target(AS_Host
*host
)
554 return '0' + host
->SCpnt
->device
->id
;
559 * Prototype: cmdtype_t acornscsi_cmdtype(int command)
560 * Purpose : differentiate READ from WRITE from other commands
561 * Params : command - command to interpret
562 * Returns : CMD_READ - command reads data,
563 * CMD_WRITE - command writes data,
564 * CMD_MISC - everything else
567 cmdtype_t
acornscsi_cmdtype(int command
)
570 case WRITE_6
: case WRITE_10
: case WRITE_12
:
572 case READ_6
: case READ_10
: case READ_12
:
580 * Prototype: int acornscsi_datadirection(int command)
581 * Purpose : differentiate between commands that have a DATA IN phase
582 * and a DATA OUT phase
583 * Params : command - command to interpret
584 * Returns : DATADIR_OUT - data out phase expected
585 * DATADIR_IN - data in phase expected
588 datadir_t
acornscsi_datadirection(int command
)
591 case CHANGE_DEFINITION
: case COMPARE
: case COPY
:
592 case COPY_VERIFY
: case LOG_SELECT
: case MODE_SELECT
:
593 case MODE_SELECT_10
: case SEND_DIAGNOSTIC
: case WRITE_BUFFER
:
594 case FORMAT_UNIT
: case REASSIGN_BLOCKS
: case RESERVE
:
595 case SEARCH_EQUAL
: case SEARCH_HIGH
: case SEARCH_LOW
:
596 case WRITE_6
: case WRITE_10
: case WRITE_VERIFY
:
597 case UPDATE_BLOCK
: case WRITE_LONG
: case WRITE_SAME
:
598 case SEARCH_HIGH_12
: case SEARCH_EQUAL_12
: case SEARCH_LOW_12
:
599 case WRITE_12
: case WRITE_VERIFY_12
: case SET_WINDOW
:
600 case MEDIUM_SCAN
: case SEND_VOLUME_TAG
: case 0xea:
608 * Purpose : provide values for synchronous transfers with 33C93.
609 * Copyright: Copyright (c) 1996 John Shifflett, GeoLog Consulting
610 * Modified by Russell King for 8MHz WD33C93A
612 static struct sync_xfer_tbl
{
613 unsigned int period_ns
;
614 unsigned char reg_value
;
615 } sync_xfer_table
[] = {
616 { 1, 0x20 }, { 249, 0x20 }, { 374, 0x30 },
617 { 499, 0x40 }, { 624, 0x50 }, { 749, 0x60 },
618 { 874, 0x70 }, { 999, 0x00 }, { 0, 0 }
622 * Prototype: int acornscsi_getperiod(unsigned char syncxfer)
623 * Purpose : period for the synchronous transfer setting
624 * Params : syncxfer SYNCXFER register value
625 * Returns : period in ns.
628 int acornscsi_getperiod(unsigned char syncxfer
)
633 if (syncxfer
== 0x10)
636 for (i
= 1; sync_xfer_table
[i
].period_ns
; i
++)
637 if (syncxfer
== sync_xfer_table
[i
].reg_value
)
638 return sync_xfer_table
[i
].period_ns
;
643 * Prototype: int round_period(unsigned int period)
644 * Purpose : return index into above table for a required REQ period
645 * Params : period - time (ns) for REQ
646 * Returns : table index
647 * Copyright: Copyright (c) 1996 John Shifflett, GeoLog Consulting
650 int round_period(unsigned int period
)
654 for (i
= 1; sync_xfer_table
[i
].period_ns
; i
++) {
655 if ((period
<= sync_xfer_table
[i
].period_ns
) &&
656 (period
> sync_xfer_table
[i
- 1].period_ns
))
663 * Prototype: unsigned char calc_sync_xfer(unsigned int period, unsigned int offset)
664 * Purpose : calculate value for 33c93s SYNC register
665 * Params : period - time (ns) for REQ
666 * offset - offset in bytes between REQ/ACK
667 * Returns : value for SYNC register
668 * Copyright: Copyright (c) 1996 John Shifflett, GeoLog Consulting
671 unsigned char __maybe_unused
calc_sync_xfer(unsigned int period
,
674 return sync_xfer_table
[round_period(period
)].reg_value
|
675 ((offset
< SDTR_SIZE
) ? offset
: SDTR_SIZE
);
678 /* ====================================================================================
682 * Function: acornscsi_kick(AS_Host *host)
683 * Purpose : kick next command to interface
684 * Params : host - host to send command to
685 * Returns : INTR_IDLE if idle, otherwise INTR_PROCESSING
686 * Notes : interrupts are always disabled!
689 intr_ret_t
acornscsi_kick(AS_Host
*host
)
692 struct scsi_cmnd
*SCpnt
;
694 /* first check to see if a command is waiting to be executed */
695 SCpnt
= host
->origSCpnt
;
696 host
->origSCpnt
= NULL
;
698 /* retrieve next command */
700 SCpnt
= queue_remove_exclude(&host
->queues
.issue
, host
->busyluns
);
707 if (host
->scsi
.disconnectable
&& host
->SCpnt
) {
708 queue_add_cmd_tail(&host
->queues
.disconnected
, host
->SCpnt
);
709 host
->scsi
.disconnectable
= 0;
710 #if (DEBUG & (DEBUG_QUEUES|DEBUG_DISCON))
711 DBG(host
->SCpnt
, printk("scsi%d.%c: moved command to disconnected queue\n",
712 host
->host
->host_no
, acornscsi_target(host
)));
718 * If we have an interrupt pending, then we may have been reselected.
719 * In this case, we don't want to write to the registers
721 if (!(sbic_arm_read(host
, SBIC_ASR
) & (ASR_INT
|ASR_BSY
|ASR_CIP
))) {
722 sbic_arm_write(host
, SBIC_DESTID
, SCpnt
->device
->id
);
723 sbic_arm_write(host
, SBIC_CMND
, CMND_SELWITHATN
);
727 * claim host busy - all of these must happen atomically wrt
728 * our interrupt routine. Failure means command loss.
730 host
->scsi
.phase
= PHASE_CONNECTING
;
732 host
->scsi
.SCp
= *arm_scsi_pointer(SCpnt
);
733 host
->dma
.xfer_setup
= 0;
734 host
->dma
.xfer_required
= 0;
735 host
->dma
.xfer_done
= 0;
737 #if (DEBUG & (DEBUG_ABORT|DEBUG_CONNECT))
738 DBG(SCpnt
,printk("scsi%d.%c: starting cmd %02X\n",
739 host
->host
->host_no
, '0' + SCpnt
->device
->id
,
744 set_bit(SCpnt
->device
->id
* 8 +
745 (u8
)(SCpnt
->device
->lun
& 0x07), host
->busyluns
);
747 host
->stats
.removes
+= 1;
749 switch (acornscsi_cmdtype(SCpnt
->cmnd
[0])) {
751 host
->stats
.writes
+= 1;
754 host
->stats
.reads
+= 1;
757 host
->stats
.miscs
+= 1;
762 return INTR_PROCESSING
;
766 * Function: void acornscsi_done(AS_Host *host, struct scsi_cmnd **SCpntp, unsigned int result)
767 * Purpose : complete processing for command
768 * Params : host - interface that completed
769 * result - driver byte of result
771 static void acornscsi_done(AS_Host
*host
, struct scsi_cmnd
**SCpntp
,
774 struct scsi_cmnd
*SCpnt
= *SCpntp
;
777 sbic_arm_write(host
, SBIC_SOURCEID
, SOURCEID_ER
| SOURCEID_DSP
);
779 host
->stats
.fins
+= 1;
784 acornscsi_dma_cleanup(host
);
786 set_host_byte(SCpnt
, result
);
787 if (result
== DID_OK
)
788 scsi_msg_to_host_byte(SCpnt
, host
->scsi
.SCp
.Message
);
789 set_status_byte(SCpnt
, host
->scsi
.SCp
.Status
);
792 * In theory, this should not happen. In practice, it seems to.
793 * Only trigger an error if the device attempts to report all happy
794 * but with untransferred buffers... If we don't do something, then
795 * data loss will occur. Should we check SCpnt->underflow here?
796 * It doesn't appear to be set to something meaningful by the higher
797 * levels all the time.
799 if (result
== DID_OK
) {
802 if (SCpnt
->underflow
== 0) {
803 if (host
->scsi
.SCp
.ptr
&&
804 acornscsi_cmdtype(SCpnt
->cmnd
[0]) != CMD_MISC
)
807 if (host
->scsi
.SCp
.scsi_xferred
< SCpnt
->underflow
||
808 host
->scsi
.SCp
.scsi_xferred
!= host
->dma
.transferred
)
812 /* ANSI standard says: (SCSI-2 Rev 10c Sect 5.6.6)
813 * Targets which break data transfers into multiple
814 * connections shall end each successful connection
815 * (except possibly the last) with a SAVE DATA
816 * POINTER - DISCONNECT message sequence.
818 * This makes it difficult to ensure that a transfer has
819 * completed. If we reach the end of a transfer during
820 * the command, then we can only have finished the transfer.
821 * therefore, if we seem to have some data remaining, this
824 if (host
->dma
.xfer_done
)
828 switch (get_status_byte(SCpnt
)) {
829 case SAM_STAT_CHECK_CONDITION
:
830 case SAM_STAT_COMMAND_TERMINATED
:
832 case SAM_STAT_TASK_SET_FULL
:
833 case SAM_STAT_RESERVATION_CONFLICT
:
837 scmd_printk(KERN_ERR
, SCpnt
,
838 "incomplete data transfer detected: "
839 "result=%08X", SCpnt
->result
);
840 scsi_print_command(SCpnt
);
841 acornscsi_dumpdma(host
, "done");
842 acornscsi_dumplog(host
, SCpnt
->device
->id
);
843 set_host_byte(SCpnt
, DID_ERROR
);
848 clear_bit(SCpnt
->device
->id
* 8 +
849 (u8
)(SCpnt
->device
->lun
& 0x7), host
->busyluns
);
853 printk("scsi%d: null command in acornscsi_done", host
->host
->host_no
);
855 host
->scsi
.phase
= PHASE_IDLE
;
858 /* ====================================================================================
862 * Purpose : update SCSI Data Pointer
863 * Notes : this will only be one SG entry or less
866 void acornscsi_data_updateptr(AS_Host
*host
, struct scsi_pointer
*SCp
, unsigned int length
)
869 SCp
->this_residual
-= length
;
871 if (SCp
->this_residual
== 0 && next_SCp(SCp
) == 0)
872 host
->dma
.xfer_done
= 1;
876 * Prototype: void acornscsi_data_read(AS_Host *host, char *ptr,
877 * unsigned int start_addr, unsigned int length)
878 * Purpose : read data from DMA RAM
879 * Params : host - host to transfer from
881 * start_addr - host mem address
882 * length - number of bytes to transfer
883 * Notes : this will only be one SG entry or less
886 void acornscsi_data_read(AS_Host
*host
, char *ptr
,
887 unsigned int start_addr
, unsigned int length
)
889 extern void __acornscsi_in(void __iomem
*, char *buf
, int len
);
890 unsigned int page
, offset
, len
= length
;
892 page
= (start_addr
>> 12);
893 offset
= start_addr
& ((1 << 12) - 1);
895 writeb((page
& 0x3f) | host
->card
.page_reg
, host
->fast
+ PAGE_REG
);
898 unsigned int this_len
;
900 if (len
+ offset
> (1 << 12))
901 this_len
= (1 << 12) - offset
;
905 __acornscsi_in(host
->base
+ (offset
<< 1), ptr
, this_len
);
911 if (offset
== (1 << 12)) {
914 writeb((page
& 0x3f) | host
->card
.page_reg
, host
->fast
+ PAGE_REG
);
917 writeb(host
->card
.page_reg
, host
->fast
+ PAGE_REG
);
921 * Prototype: void acornscsi_data_write(AS_Host *host, char *ptr,
922 * unsigned int start_addr, unsigned int length)
923 * Purpose : write data to DMA RAM
924 * Params : host - host to transfer from
926 * start_addr - host mem address
927 * length - number of bytes to transfer
928 * Notes : this will only be one SG entry or less
931 void acornscsi_data_write(AS_Host
*host
, char *ptr
,
932 unsigned int start_addr
, unsigned int length
)
934 extern void __acornscsi_out(void __iomem
*, char *buf
, int len
);
935 unsigned int page
, offset
, len
= length
;
937 page
= (start_addr
>> 12);
938 offset
= start_addr
& ((1 << 12) - 1);
940 writeb((page
& 0x3f) | host
->card
.page_reg
, host
->fast
+ PAGE_REG
);
943 unsigned int this_len
;
945 if (len
+ offset
> (1 << 12))
946 this_len
= (1 << 12) - offset
;
950 __acornscsi_out(host
->base
+ (offset
<< 1), ptr
, this_len
);
956 if (offset
== (1 << 12)) {
959 writeb((page
& 0x3f) | host
->card
.page_reg
, host
->fast
+ PAGE_REG
);
962 writeb(host
->card
.page_reg
, host
->fast
+ PAGE_REG
);
965 /* =========================================================================================
966 * On-board DMA routines
970 * Prototype: void acornscsi_dmastop(AS_Host *host)
971 * Purpose : stop all DMA
972 * Params : host - host on which to stop DMA
973 * Notes : This is called when leaving DATA IN/OUT phase,
974 * or when interface is RESET
977 void acornscsi_dma_stop(AS_Host
*host
)
979 dmac_write(host
, DMAC_MASKREG
, MASK_ON
);
980 dmac_clearintr(host
);
982 #if (DEBUG & DEBUG_DMA)
983 DBG(host
->SCpnt
, acornscsi_dumpdma(host
, "stop"));
988 * Function: void acornscsi_dma_setup(AS_Host *host, dmadir_t direction)
989 * Purpose : setup DMA controller for data transfer
990 * Params : host - host to setup
991 * direction - data transfer direction
992 * Notes : This is called when entering DATA I/O phase, not
993 * while we're in a DATA I/O phase
996 void acornscsi_dma_setup(AS_Host
*host
, dmadir_t direction
)
998 unsigned int address
, length
, mode
;
1000 host
->dma
.direction
= direction
;
1002 dmac_write(host
, DMAC_MASKREG
, MASK_ON
);
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
));
1017 * Allocate some buffer space, limited to half the buffer size
1019 length
= min_t(unsigned int, host
->scsi
.SCp
.this_residual
, DMAC_BUFFER_SIZE
/ 2);
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);
1026 * Transfer data to DMA memory
1028 if (direction
== DMA_OUT
)
1029 acornscsi_data_write(host
, host
->scsi
.SCp
.ptr
, host
->dma
.start_addr
,
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
);
1041 #if (DEBUG & DEBUG_DMA)
1042 DBG(host
->SCpnt
, acornscsi_dumpdma(host
, "strt"));
1044 host
->dma
.xfer_setup
= 1;
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.
1057 void acornscsi_dma_cleanup(AS_Host
*host
)
1059 dmac_write(host
, DMAC_MASKREG
, MASK_ON
);
1060 dmac_clearintr(host
);
1063 * Check for a pending transfer
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
);
1073 * Has a transfer been setup?
1075 if (host
->dma
.xfer_setup
) {
1076 unsigned int transferred
;
1078 host
->dma
.xfer_setup
= 0;
1080 #if (DEBUG & DEBUG_DMA)
1081 DBG(host
->SCpnt
, acornscsi_dumpdma(host
, "cupi"));
1085 * Calculate number of bytes transferred from DMA.
1087 transferred
= dmac_address(host
) - host
->dma
.start_addr
;
1088 host
->dma
.transferred
+= transferred
;
1090 if (host
->dma
.direction
== DMA_IN
)
1091 acornscsi_data_read(host
, host
->scsi
.SCp
.ptr
,
1092 host
->dma
.start_addr
, transferred
);
1095 * Update SCSI pointers
1097 acornscsi_data_updateptr(host
, &host
->scsi
.SCp
, transferred
);
1098 #if (DEBUG & DEBUG_DMA)
1099 DBG(host
->SCpnt
, acornscsi_dumpdma(host
, "cupo"));
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
1112 * : Called whenever DMAC finished it's current transfer.
1115 void acornscsi_dma_intr(AS_Host
*host
)
1117 unsigned int address
, length
, transferred
;
1119 #if (DEBUG & DEBUG_DMA)
1120 DBG(host
->SCpnt
, acornscsi_dumpdma(host
, "inti"));
1123 dmac_write(host
, DMAC_MASKREG
, MASK_ON
);
1124 dmac_clearintr(host
);
1127 * Calculate amount transferred via DMA
1129 transferred
= dmac_address(host
) - host
->dma
.start_addr
;
1130 host
->dma
.transferred
+= transferred
;
1133 * Schedule DMA transfer off board
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;
1142 acornscsi_data_updateptr(host
, &host
->scsi
.SCp
, transferred
);
1145 * Allocate some buffer space, limited to half the on-board RAM size
1147 length
= min_t(unsigned int, host
->scsi
.SCp
.this_residual
, DMAC_BUFFER_SIZE
/ 2);
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);
1154 * Transfer data to DMA memory
1156 if (host
->dma
.direction
== DMA_OUT
)
1157 acornscsi_data_write(host
, host
->scsi
.SCp
.ptr
, host
->dma
.start_addr
,
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
);
1168 #if (DEBUG & DEBUG_DMA)
1169 DBG(host
->SCpnt
, acornscsi_dumpdma(host
, "into"));
1172 host
->dma
.xfer_setup
= 0;
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.
1180 if (dmac_read(host
, DMAC_STATUS
) & STATUS_RQ0
) {
1181 acornscsi_abortcmd(host
);
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
);
1195 * Function: void acornscsi_dma_xfer(AS_Host *host)
1196 * Purpose : transfer data between AcornSCSI and memory
1197 * Params : host - host to process
1200 void acornscsi_dma_xfer(AS_Host
*host
)
1202 host
->dma
.xfer_required
= 0;
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
);
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
1216 void acornscsi_dma_adjust(AS_Host
*host
)
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"));
1224 * Calculate correct DMA address - DMA is ahead of SCSI bus while
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.
1231 * real_dma_addr = host->dma.start_addr + host->scsi.SCp.scsi_xferred
1232 * - host->dma.transferred
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;
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"));
1253 /* =========================================================================================
1257 acornscsi_write_pio(AS_Host
*host
, char *bytes
, int *ptr
, int len
, unsigned int max_timeout
)
1259 unsigned int asr
, timeout
= max_timeout
;
1262 while (my_ptr
< len
) {
1263 asr
= sbic_arm_read(host
, SBIC_ASR
);
1265 if (asr
& ASR_DBR
) {
1266 timeout
= max_timeout
;
1268 sbic_arm_write(host
, SBIC_DATA
, bytes
[my_ptr
++]);
1269 } else if (asr
& ASR_INT
)
1271 else if (--timeout
== 0)
1278 return (timeout
== 0) ? -1 : 0;
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
1287 acornscsi_sendcommand(AS_Host
*host
)
1289 struct scsi_cmnd
*SCpnt
= host
->SCpnt
;
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
);
1295 acornscsi_sbic_issuecmd(host
, CMND_XFERINFO
);
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
);
1301 host
->scsi
.phase
= PHASE_COMMAND
;
1305 void acornscsi_sendmessage(AS_Host
*host
)
1307 unsigned int message_length
= msgqueue_msglength(&host
->scsi
.msgs
);
1309 struct message
*msg
;
1311 #if (DEBUG & DEBUG_MESSAGES)
1312 printk("scsi%d.%c: sending message ",
1313 host
->host
->host_no
, acornscsi_target(host
));
1316 switch (message_length
) {
1318 acornscsi_sbic_issuecmd(host
, CMND_XFERINFO
| CMND_SBT
);
1320 acornscsi_sbic_wait(host
, ASR_DBR
, ASR_DBR
, 1000, "sending message 1");
1322 sbic_arm_write(host
, SBIC_DATA
, NOP
);
1324 host
->scsi
.last_message
= NOP
;
1325 #if (DEBUG & DEBUG_MESSAGES)
1331 acornscsi_sbic_issuecmd(host
, CMND_XFERINFO
| CMND_SBT
);
1332 msg
= msgqueue_getmsg(&host
->scsi
.msgs
, 0);
1334 acornscsi_sbic_wait(host
, ASR_DBR
, ASR_DBR
, 1000, "sending message 2");
1336 sbic_arm_write(host
, SBIC_DATA
, msg
->msg
[0]);
1338 host
->scsi
.last_message
= msg
->msg
[0];
1339 #if (DEBUG & DEBUG_MESSAGES)
1340 spi_print_msg(msg
->msg
);
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.
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
);
1359 while ((msg
= msgqueue_getmsg(&host
->scsi
.msgs
, msgnr
++)) != NULL
) {
1361 #if (DEBUG & DEBUG_MESSAGES)
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
);
1368 host
->scsi
.last_message
= msg
->msg
[0];
1369 if (msg
->msg
[0] == EXTENDED_MESSAGE
)
1370 host
->scsi
.last_message
|= msg
->msg
[2] << 8;
1372 if (i
!= msg
->length
)
1377 #if (DEBUG & DEBUG_MESSAGES)
1383 * Function: void acornscsi_readstatusbyte(AS_Host *host)
1384 * Purpose : Read status byte from connected target
1385 * Params : host - host connected to target
1388 void acornscsi_readstatusbyte(AS_Host
*host
)
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
);
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
1401 unsigned char acornscsi_readmessagebyte(AS_Host
*host
)
1403 unsigned char message
;
1405 acornscsi_sbic_issuecmd(host
, CMND_XFERINFO
| CMND_SBT
);
1407 acornscsi_sbic_wait(host
, ASR_DBR
, ASR_DBR
, 1000, "for message byte");
1409 message
= sbic_arm_read(host
, SBIC_DATA
);
1411 /* wait for MSGIN-XFER-PAUSED */
1412 acornscsi_sbic_wait(host
, ASR_INT
, ASR_INT
, 1000, "for interrupt after message byte");
1414 sbic_arm_read(host
, SBIC_SSR
);
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
1425 void acornscsi_message(AS_Host
*host
)
1427 struct scsi_pointer
*scsi_pointer
;
1428 unsigned char message
[16];
1429 unsigned int msgidx
= 0, msglen
= 1;
1432 message
[msgidx
] = acornscsi_readmessagebyte(host
);
1436 if (message
[0] == EXTENDED_MESSAGE
||
1437 (message
[0] >= 0x20 && message
[0] <= 0x2f))
1442 if (message
[0] == EXTENDED_MESSAGE
)
1443 msglen
+= message
[msgidx
];
1447 if (msgidx
< msglen
) {
1448 acornscsi_sbic_issuecmd(host
, CMND_NEGATEACK
);
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
);
1454 } while (msgidx
< msglen
);
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
);
1463 if (host
->scsi
.phase
== PHASE_RECONNECTED
) {
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...'
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
;
1476 switch (message
[0]) {
1477 case ABORT_TASK_SET
:
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
);
1485 host
->scsi
.phase
= PHASE_DONE
;
1486 host
->scsi
.SCp
.Message
= message
[0];
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.
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
;
1503 case RESTORE_POINTERS
:
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.'
1513 acornscsi_dma_cleanup(host
);
1514 host
->scsi
.SCp
= *arm_scsi_pointer(host
->SCpnt
);
1515 host
->scsi
.phase
= PHASE_MSGIN
;
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.'
1528 acornscsi_dma_cleanup(host
);
1529 host
->scsi
.phase
= PHASE_DISCONNECT
;
1532 case MESSAGE_REJECT
:
1533 #if 0 /* this isn't needed any more */
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.
1540 if (host
->device
[host
->SCpnt
->device
->id
].sync_state
== SYNC_SENT_REQUEST
)
1541 host
->device
[host
->SCpnt
->device
->id
].sync_state
= SYNC_NEGOCIATE
;
1545 * If we have any messages waiting to go out, then assert ATN now
1547 if (msgqueue_msglength(&host
->scsi
.msgs
))
1548 acornscsi_sbic_issuecmd(host
, CMND_ASSERTATN
);
1550 switch (host
->scsi
.last_message
) {
1551 case EXTENDED_MESSAGE
| (EXTENDED_SDTR
<< 8):
1553 * Target can't handle synchronous transfers
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
);
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
),
1574 case EXTENDED_MESSAGE
:
1575 switch (message
[2]) {
1576 #ifdef CONFIG_SCSI_ACORNSCSI_SYNC
1578 if (host
->device
[host
->SCpnt
->device
->id
].sync_state
== SYNC_SENT_REQUEST
) {
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
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]);
1592 unsigned char period
, length
;
1594 * Target requested synchronous transfers. The agreement is only
1595 * to be in operation AFTER the target leaves message out phase.
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
);
1605 sbic_arm_write(host
, SBIC_SYNCHTRANSFER
, host
->device
[host
->SCpnt
->device
->id
].sync_xfer
);
1608 /* We do not accept synchronous transfers. Respond with a
1614 /* The WD33C93A is only 8-bit. We respond with a MESSAGE_REJECT
1615 * to a wide data transfer request.
1618 acornscsi_sbic_issuecmd(host
, CMND_ASSERTATN
);
1619 msgqueue_flush(&host
->scsi
.msgs
);
1620 msgqueue_addmsg(&host
->scsi
.msgs
, 1, MESSAGE_REJECT
);
1625 default: /* reject message */
1626 printk(KERN_ERR
"scsi%d.%c: unrecognised message %02X, rejecting\n",
1627 host
->host
->host_no
, acornscsi_target(host
),
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
;
1635 acornscsi_sbic_issuecmd(host
, CMND_NEGATEACK
);
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
1644 void acornscsi_buildmessages(AS_Host
*host
)
1647 /* does the device need resetting? */
1649 msgqueue_addmsg(&host
->scsi
.msgs
, 1, BUS_DEVICE_RESET
);
1654 msgqueue_addmsg(&host
->scsi
.msgs
, 1,
1655 IDENTIFY(host
->device
[host
->SCpnt
->device
->id
].disconnect_ok
,
1656 host
->SCpnt
->device
->lun
));
1659 /* does the device need the current command aborted */
1661 acornscsi_abortcmd(host
);
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
);
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
1684 int acornscsi_starttransfer(AS_Host
*host
)
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
));
1694 residual
= scsi_bufflen(host
->SCpnt
) - host
->scsi
.SCp
.scsi_xferred
;
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
);
1704 /* =========================================================================================
1705 * Connection & Disconnection
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'
1716 int acornscsi_reconnect(AS_Host
*host
)
1718 unsigned int target
, lun
, ok
= 0;
1720 target
= sbic_arm_read(host
, SBIC_SOURCEID
);
1723 printk(KERN_ERR
"scsi%d: invalid source id after reselection "
1724 "- device fault?\n",
1725 host
->host
->host_no
);
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
);
1736 lun
= sbic_arm_read(host
, SBIC_DATA
) & 7;
1738 host
->scsi
.reconnected
.target
= target
;
1739 host
->scsi
.reconnected
.lun
= lun
;
1740 host
->scsi
.reconnected
.tag
= 0;
1742 if (host
->scsi
.disconnectable
&& host
->SCpnt
&&
1743 host
->SCpnt
->device
->id
== target
&& host
->SCpnt
->device
->lun
== lun
)
1746 if (!ok
&& queue_probetgtlun(&host
->queues
.disconnected
, target
, lun
))
1749 ADD_STATUS(target
, 0x81, host
->scsi
.phase
, 0);
1752 host
->scsi
.phase
= PHASE_RECONNECTED
;
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
);
1761 queue_add_cmd_tail(&host
->queues
.disconnected
, host
->SCpnt
);
1765 acornscsi_sbic_issuecmd(host
, CMND_NEGATEACK
);
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
1776 int acornscsi_reconnect_finish(AS_Host
*host
)
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
)));
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
)));
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
)));
1809 acornscsi_abortcmd(host
);
1812 * Restore data pointer from SAVED pointers.
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
);
1820 #if (DEBUG & (DEBUG_QUEUES|DEBUG_DISCON))
1824 host
->dma
.transferred
= host
->scsi
.SCp
.scsi_xferred
;
1826 return host
->SCpnt
!= NULL
;
1830 * Function: void acornscsi_disconnect_unexpected(AS_Host *host)
1831 * Purpose : handle an unexpected disconnect
1832 * Params : host - host on which disconnect occurred
1835 void acornscsi_disconnect_unexpected(AS_Host
*host
)
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);
1843 acornscsi_done(host
, &host
->SCpnt
, DID_ERROR
);
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
1852 void acornscsi_abortcmd(AS_Host
*host
)
1854 host
->scsi
.phase
= PHASE_ABORTED
;
1855 sbic_arm_write(host
, SBIC_CMND
, CMND_ASSERTATN
);
1857 msgqueue_flush(&host
->scsi
.msgs
);
1858 msgqueue_addmsg(&host
->scsi
.msgs
, 1, ABORT
);
1861 /* ==========================================================================================
1862 * Interrupt routines.
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
1873 intr_ret_t
acornscsi_sbicintr(AS_Host
*host
, int in_irq
)
1875 unsigned int asr
, ssr
;
1877 asr
= sbic_arm_read(host
, SBIC_ASR
);
1878 if (!(asr
& ASR_INT
))
1881 ssr
= sbic_arm_read(host
, SBIC_SSR
);
1883 #if (DEBUG & DEBUG_PHASES)
1884 print_sbic_status(asr
, ssr
, host
->scsi
.phase
);
1887 ADD_STATUS(8, ssr
, host
->scsi
.phase
, in_irq
);
1889 if (host
->SCpnt
&& !host
->scsi
.disconnectable
)
1890 ADD_STATUS(host
->SCpnt
->device
->id
, ssr
, host
->scsi
.phase
, in_irq
);
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
);
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
);
1909 case 0x41: /* unexpected disconnect aborted command */
1910 acornscsi_disconnect_unexpected(host
);
1911 return INTR_NEXT_COMMAND
;
1914 switch (host
->scsi
.phase
) {
1915 case PHASE_CONNECTING
: /* STATE: command removed from issue queue */
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
))
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);
1931 case 0x42: /* select timed out */
1933 acornscsi_done(host
, &host
->SCpnt
, DID_NO_CONNECT
);
1934 return INTR_NEXT_COMMAND
;
1936 case 0x81: /* -> PHASE_RECONNECTED or PHASE_ABORTED */
1937 /* BUS FREE -> RESELECTION */
1938 host
->origSCpnt
= host
->SCpnt
;
1940 msgqueue_flush(&host
->scsi
.msgs
);
1941 acornscsi_reconnect(host
);
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
);
1950 return INTR_PROCESSING
;
1953 case PHASE_CONNECTED
: /* STATE: device selected ok */
1956 case 0x8a: /* -> PHASE_COMMAND, PHASE_COMMANDPAUSED */
1957 /* SELECTION -> COMMAND */
1958 acornscsi_sendcommand(host
);
1961 case 0x8b: /* -> PHASE_STATUS */
1962 /* SELECTION -> STATUS */
1963 acornscsi_readstatusbyte(host
);
1964 host
->scsi
.phase
= PHASE_STATUSIN
;
1968 case 0x8e: /* -> PHASE_MSGOUT */
1969 /* SELECTION ->MESSAGE OUT */
1970 host
->scsi
.phase
= PHASE_MSGOUT
;
1971 acornscsi_buildmessages(host
);
1972 acornscsi_sendmessage(host
);
1975 /* these should not happen */
1976 case 0x85: /* target disconnected */
1977 acornscsi_done(host
, &host
->SCpnt
, DID_ERROR
);
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
);
1986 return INTR_PROCESSING
;
1988 case PHASE_MSGOUT
: /* STATE: connected & sent IDENTIFY message */
1990 * SCSI standard says that MESSAGE OUT phases can be followed by a
1991 * DATA phase, STATUS phase, MESSAGE IN phase or COMMAND phase
1994 case 0x8a: /* -> PHASE_COMMAND, PHASE_COMMANDPAUSED */
1995 case 0x1a: /* -> PHASE_COMMAND, PHASE_COMMANDPAUSED */
1996 /* MESSAGE OUT -> COMMAND */
1997 acornscsi_sendcommand(host
);
2000 case 0x8b: /* -> PHASE_STATUS */
2001 case 0x1b: /* -> PHASE_STATUS */
2002 /* MESSAGE OUT -> STATUS */
2003 acornscsi_readstatusbyte(host
);
2004 host
->scsi
.phase
= PHASE_STATUSIN
;
2007 case 0x8e: /* -> PHASE_MSGOUT */
2008 /* MESSAGE_OUT(MESSAGE_IN) ->MESSAGE OUT */
2009 acornscsi_sendmessage(host
);
2012 case 0x4f: /* -> PHASE_MSGIN, PHASE_DISCONNECT */
2013 case 0x1f: /* -> PHASE_MSGIN, PHASE_DISCONNECT */
2014 /* MESSAGE OUT -> MESSAGE IN */
2015 acornscsi_message(host
);
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);
2023 return INTR_PROCESSING
;
2025 case PHASE_COMMAND
: /* STATE: connected & command sent */
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
;
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
;
2047 case 0x1b: /* -> PHASE_STATUS */
2048 /* COMMAND -> STATUS */
2049 acornscsi_readstatusbyte(host
);
2050 host
->scsi
.phase
= PHASE_STATUSIN
;
2053 case 0x1e: /* -> PHASE_MSGOUT */
2054 /* COMMAND -> MESSAGE OUT */
2055 acornscsi_sendmessage(host
);
2058 case 0x1f: /* -> PHASE_MSGIN, PHASE_DISCONNECT */
2059 /* COMMAND -> MESSAGE IN */
2060 acornscsi_message(host
);
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);
2068 return INTR_PROCESSING
;
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;
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);
2081 return INTR_NEXT_COMMAND
;
2083 case PHASE_IDLE
: /* STATE: disconnected */
2084 if (ssr
== 0x81) /* -> PHASE_RECONNECTED or PHASE_ABORTED */
2085 acornscsi_reconnect(host
);
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);
2091 return INTR_PROCESSING
;
2093 case PHASE_RECONNECTED
: /* STATE: device reconnected to initiator */
2095 * Command reconnected - if MESGIN, get message - it may be
2096 * the tag. If not, get command out of disconnected queue
2099 * If we reconnected and we're not in MESSAGE IN phase after IDENTIFY,
2100 * reconnect I_T_L command
2102 if (ssr
!= 0x8f && !acornscsi_reconnect_finish(host
))
2104 ADD_STATUS(host
->SCpnt
->device
->id
, ssr
, host
->scsi
.phase
, in_irq
);
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
;
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
;
2124 case 0x8a: /* command out */
2125 /* MESSAGE IN -> COMMAND */
2126 acornscsi_sendcommand(host
);/* -> PHASE_COMMAND, PHASE_COMMANDPAUSED */
2129 case 0x8b: /* status in */
2130 /* -> PHASE_STATUSIN */
2131 /* MESSAGE IN -> STATUS */
2132 acornscsi_readstatusbyte(host
);
2133 host
->scsi
.phase
= PHASE_STATUSIN
;
2136 case 0x8e: /* message out */
2137 /* -> PHASE_MSGOUT */
2138 /* MESSAGE IN -> MESSAGE OUT */
2139 acornscsi_sendmessage(host
);
2142 case 0x8f: /* message in */
2143 acornscsi_message(host
); /* -> PHASE_MSGIN, PHASE_DISCONNECT */
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);
2151 return INTR_PROCESSING
;
2153 case PHASE_DATAIN
: /* STATE: transferred data in */
2155 * This is simple - if we disconnect then the DMA address & count is
2159 case 0x19: /* -> PHASE_DATAIN */
2160 case 0x89: /* -> PHASE_DATAIN */
2161 acornscsi_abortcmd(host
);
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
;
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
);
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 */
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);
2200 return INTR_PROCESSING
;
2202 case PHASE_DATAOUT
: /* STATE: transferred data out */
2204 * This is more complicated - if we disconnect, the DMA could be 12
2205 * bytes ahead of us. We need to correct this.
2208 case 0x18: /* -> PHASE_DATAOUT */
2209 case 0x88: /* -> PHASE_DATAOUT */
2210 acornscsi_abortcmd(host
);
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
;
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
);
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 */
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);
2252 return INTR_PROCESSING
;
2254 case PHASE_STATUSIN
: /* STATE: status in complete */
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
);
2262 case 0x1e: /* -> PHASE_MSGOUT */
2263 case 0x8e: /* -> PHASE_MSGOUT */
2264 /* STATUS -> MESSAGE OUT */
2265 acornscsi_sendmessage(host
);
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);
2273 return INTR_PROCESSING
;
2275 case PHASE_MSGIN
: /* STATE: message in */
2277 case 0x1e: /* -> PHASE_MSGOUT */
2278 case 0x4e: /* -> PHASE_MSGOUT */
2279 case 0x8e: /* -> PHASE_MSGOUT */
2280 /* MESSAGE IN -> MESSAGE OUT */
2281 acornscsi_sendmessage(host
);
2284 case 0x1f: /* -> PHASE_MSGIN, PHASE_DONE, PHASE_DISCONNECT */
2288 acornscsi_message(host
);
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
);
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);
2303 return INTR_PROCESSING
;
2305 case PHASE_DONE
: /* STATE: received status & message */
2307 case 0x85: /* -> PHASE_IDLE */
2308 acornscsi_done(host
, &host
->SCpnt
, DID_OK
);
2309 return INTR_NEXT_COMMAND
;
2313 acornscsi_sendmessage(host
);
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);
2321 return INTR_PROCESSING
;
2327 acornscsi_done(host
, &host
->SCpnt
, DID_ABORT
);
2329 clear_bit(host
->scsi
.reconnected
.target
* 8 + host
->scsi
.reconnected
.lun
,
2331 host
->scsi
.phase
= PHASE_IDLE
;
2333 return INTR_NEXT_COMMAND
;
2339 acornscsi_sendmessage(host
);
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);
2347 return INTR_PROCESSING
;
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);
2354 return INTR_PROCESSING
;
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)
2364 acornscsi_intr(int irq
, void *dev_id
)
2366 AS_Host
*host
= (AS_Host
*)dev_id
;
2374 iostatus
= readb(host
->fast
+ INT_REG
);
2377 acornscsi_dma_intr(host
);
2378 iostatus
= readb(host
->fast
+ INT_REG
);
2382 ret
= acornscsi_sbicintr(host
, in_irq
);
2385 * If we have a transfer pending, start it.
2386 * Only start it if the interface has already started transferring
2389 if (host
->dma
.xfer_required
)
2390 acornscsi_dma_xfer(host
);
2392 if (ret
== INTR_NEXT_COMMAND
)
2393 ret
= acornscsi_kick(host
);
2396 } while (ret
!= INTR_IDLE
);
2401 /*=============================================================================================
2402 * Interfaces between interrupt handler and rest of scsi code
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.
2411 static int acornscsi_queuecmd_lck(struct scsi_cmnd
*SCpnt
)
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
;
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
);
2427 SCpnt
->host_scribble
= NULL
;
2429 scsi_pointer
->phase
= (int)acornscsi_datadirection(SCpnt
->cmnd
[0]);
2430 scsi_pointer
->sent_command
= 0;
2431 scsi_pointer
->scsi_xferred
= 0;
2435 host
->stats
.queues
+= 1;
2438 unsigned long flags
;
2440 if (!queue_add_cmd_ordered(&host
->queues
.issue
, SCpnt
)) {
2441 set_host_byte(SCpnt
, DID_ERROR
);
2445 local_irq_save(flags
);
2446 if (host
->scsi
.phase
== PHASE_IDLE
)
2447 acornscsi_kick(host
);
2448 local_irq_restore(flags
);
2453 static DEF_SCSI_QCMD(acornscsi_queuecmd
)
2455 enum res_abort
{ res_not_running
, res_success
, res_success_clear
, res_snooze
};
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
2463 static enum res_abort
acornscsi_do_abort(AS_Host
*host
, struct scsi_cmnd
*SCpnt
)
2465 enum res_abort res
= res_not_running
;
2467 if (queue_remove_cmd(&host
->queues
.issue
, SCpnt
)) {
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.
2474 //#if (DEBUG & DEBUG_ABORT)
2475 printk("on issue queue ");
2478 } else if (queue_remove_cmd(&host
->queues
.disconnected
, SCpnt
)) {
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
2486 //#if (DEBUG & DEBUG_ABORT)
2487 printk("on disconnected queue ");
2490 } else if (host
->SCpnt
== SCpnt
) {
2491 unsigned long flags
;
2493 //#if (DEBUG & DEBUG_ABORT)
2494 printk("executing ");
2497 local_irq_save(flags
);
2498 switch (host
->scsi
.phase
) {
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
2508 if (host
->scsi
.disconnectable
) {
2509 host
->scsi
.disconnectable
= 0;
2516 * If the command has connected and done nothing further,
2517 * simply force a disconnect. We also need to clear the
2520 case PHASE_CONNECTED
:
2521 sbic_arm_write(host
, SBIC_CMND
, CMND_DISCONNECT
);
2523 res
= res_success_clear
;
2527 acornscsi_abortcmd(host
);
2530 local_irq_restore(flags
);
2531 } else if (host
->origSCpnt
== SCpnt
) {
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
2538 host
->origSCpnt
= NULL
;
2539 //#if (DEBUG & DEBUG_ABORT)
2540 printk("waiting for execution ");
2542 res
= res_success_clear
;
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
2555 static int acornscsi_abort(struct scsi_cmnd
*SCpnt
)
2557 AS_Host
*host
= (AS_Host
*) SCpnt
->device
->host
->hostdata
;
2560 host
->stats
.aborts
+= 1;
2562 #if (DEBUG & DEBUG_ABORT)
2565 asr
= sbic_arm_read(host
, SBIC_ASR
);
2566 ssr
= sbic_arm_read(host
, SBIC_SSR
);
2568 printk(KERN_WARNING
"acornscsi_abort: ");
2569 print_sbic_status(asr
, ssr
, host
->scsi
.phase
);
2570 acornscsi_dumplog(host
, SCpnt
->device
->id
);
2574 printk("scsi%d: ", host
->host
->host_no
);
2576 switch (acornscsi_do_abort(host
, SCpnt
)) {
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.
2582 case res_success_clear
:
2583 //#if (DEBUG & DEBUG_ABORT)
2586 clear_bit(SCpnt
->device
->id
* 8 +
2587 (u8
)(SCpnt
->device
->lun
& 0x7), host
->busyluns
);
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.
2596 //#if (DEBUG & DEBUG_ABORT)
2597 printk("success\n");
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.
2608 //#if (DEBUG & DEBUG_ABORT)
2615 * The command could not be found (either because it completed,
2616 * or it got dropped.
2619 case res_not_running
:
2620 acornscsi_dumplog(host
, SCpnt
->device
->id
);
2622 //#if (DEBUG & DEBUG_ABORT)
2623 printk("not running\n");
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
2637 static int acornscsi_host_reset(struct scsi_cmnd
*SCpnt
)
2639 AS_Host
*host
= (AS_Host
*)SCpnt
->device
->host
->hostdata
;
2640 struct scsi_cmnd
*SCptr
;
2642 host
->stats
.resets
+= 1;
2644 #if (DEBUG & DEBUG_RESET)
2646 int asr
, ssr
, devidx
;
2648 asr
= sbic_arm_read(host
, SBIC_ASR
);
2649 ssr
= sbic_arm_read(host
, SBIC_SSR
);
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
);
2658 acornscsi_dma_stop(host
);
2661 * do hard reset. This resets all devices on this host, and so we
2662 * must set the reset status on all commands.
2664 acornscsi_resetcard(host
);
2666 while ((SCptr
= queue_remove(&host
->queues
.disconnected
)) != NULL
)
2672 /*==============================================================================================
2673 * initialisation & miscellaneous support
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
2682 static const char *acornscsi_info(struct Scsi_Host
*host
)
2684 static char string
[100], *p
;
2688 p
+= sprintf(string
, "%s at port %08lX irq %d v%d.%d.%d"
2689 #ifdef CONFIG_SCSI_ACORNSCSI_SYNC
2692 #if (DEBUG & DEBUG_NO_WRITE)
2693 " NOWRITE (" __stringify(NO_WRITE
) ")"
2695 , host
->hostt
->name
, host
->io_port
, host
->irq
,
2696 VER_MAJOR
, VER_MINOR
, VER_PATCH
);
2700 static int acornscsi_show_info(struct seq_file
*m
, struct Scsi_Host
*instance
)
2703 struct scsi_device
*scd
;
2706 host
= (AS_Host
*)instance
->hostdata
;
2708 seq_printf(m
, "AcornSCSI driver v%d.%d.%d"
2709 #ifdef CONFIG_SCSI_ACORNSCSI_SYNC
2712 #if (DEBUG & DEBUG_NO_WRITE)
2713 " NOWRITE (" __stringify(NO_WRITE
) ")"
2715 "\n\n", VER_MAJOR
, VER_MINOR
, VER_PATCH
);
2717 seq_printf(m
, "SBIC: WD33C93A Address: %p IRQ : %d\n",
2718 host
->base
+ SBIC_REGIDX
, host
->scsi
.irq
);
2720 seq_printf(m
, "DMAC: uPC71071 Address: %p IRQ : %d\n\n",
2721 host
->base
+ DMAC_OFFSET
, host
->scsi
.irq
);
2724 seq_printf(m
, "Statistics:\n"
2725 "Queued commands: %-10u Issued commands: %-10u\n"
2726 "Done commands : %-10u Reads : %-10u\n"
2727 "Writes : %-10u Others : %-10u\n"
2728 "Disconnects : %-10u Aborts : %-10u\n"
2729 "Resets : %-10u\n\nLast phases:",
2730 host
->stats
.queues
, host
->stats
.removes
,
2731 host
->stats
.fins
, host
->stats
.reads
,
2732 host
->stats
.writes
, host
->stats
.miscs
,
2733 host
->stats
.disconnects
, host
->stats
.aborts
,
2734 host
->stats
.resets
);
2736 for (devidx
= 0; devidx
< 9; devidx
++) {
2737 unsigned int statptr
, prev
;
2739 seq_printf(m
, "\n%c:", devidx
== 8 ? 'H' : ('0' + devidx
));
2740 statptr
= host
->status_ptr
[devidx
] - 10;
2742 if ((signed int)statptr
< 0)
2743 statptr
+= STATUS_BUFFER_SIZE
;
2745 prev
= host
->status
[devidx
][statptr
].when
;
2747 for (; statptr
!= host
->status_ptr
[devidx
]; statptr
= (statptr
+ 1) & (STATUS_BUFFER_SIZE
- 1)) {
2748 if (host
->status
[devidx
][statptr
].when
) {
2749 seq_printf(m
, "%c%02X:%02X+%2ld",
2750 host
->status
[devidx
][statptr
].irq
? '-' : ' ',
2751 host
->status
[devidx
][statptr
].ph
,
2752 host
->status
[devidx
][statptr
].ssr
,
2753 (host
->status
[devidx
][statptr
].when
- prev
) < 100 ?
2754 (host
->status
[devidx
][statptr
].when
- prev
) : 99);
2755 prev
= host
->status
[devidx
][statptr
].when
;
2760 seq_printf(m
, "\nAttached devices:\n");
2762 shost_for_each_device(scd
, instance
) {
2763 seq_printf(m
, "Device/Lun TaggedQ Sync\n");
2764 seq_printf(m
, " %d/%llu ", scd
->id
, scd
->lun
);
2765 if (scd
->tagged_supported
)
2766 seq_printf(m
, "%3sabled ",
2767 scd
->simple_tags
? "en" : "dis");
2769 seq_printf(m
, "unsupported ");
2771 if (host
->device
[scd
->id
].sync_xfer
& 15)
2772 seq_printf(m
, "offset %d, %d ns\n",
2773 host
->device
[scd
->id
].sync_xfer
& 15,
2774 acornscsi_getperiod(host
->device
[scd
->id
].sync_xfer
));
2776 seq_printf(m
, "async\n");
2782 static const struct scsi_host_template acornscsi_template
= {
2783 .module
= THIS_MODULE
,
2784 .show_info
= acornscsi_show_info
,
2785 .name
= "AcornSCSI",
2786 .info
= acornscsi_info
,
2787 .queuecommand
= acornscsi_queuecmd
,
2788 .eh_abort_handler
= acornscsi_abort
,
2789 .eh_host_reset_handler
= acornscsi_host_reset
,
2792 .sg_tablesize
= SG_ALL
,
2794 .dma_boundary
= PAGE_SIZE
- 1,
2795 .proc_name
= "acornscsi",
2796 .cmd_size
= sizeof(struct arm_cmd_priv
),
2799 static int acornscsi_probe(struct expansion_card
*ec
, const struct ecard_id
*id
)
2801 struct Scsi_Host
*host
;
2805 ret
= ecard_request_resources(ec
);
2809 host
= scsi_host_alloc(&acornscsi_template
, sizeof(AS_Host
));
2815 ashost
= (AS_Host
*)host
->hostdata
;
2817 ashost
->base
= ecardm_iomap(ec
, ECARD_RES_MEMC
, 0, 0);
2818 ashost
->fast
= ecardm_iomap(ec
, ECARD_RES_IOCFAST
, 0, 0);
2819 if (!ashost
->base
|| !ashost
->fast
) {
2824 host
->irq
= ec
->irq
;
2825 ashost
->host
= host
;
2826 ashost
->scsi
.irq
= host
->irq
;
2828 ec
->irqaddr
= ashost
->fast
+ INT_REG
;
2831 ret
= request_irq(host
->irq
, acornscsi_intr
, 0, "acornscsi", ashost
);
2833 printk(KERN_CRIT
"scsi%d: IRQ%d not free: %d\n",
2834 host
->host_no
, ashost
->scsi
.irq
, ret
);
2838 memset(&ashost
->stats
, 0, sizeof (ashost
->stats
));
2839 queue_initialise(&ashost
->queues
.issue
);
2840 queue_initialise(&ashost
->queues
.disconnected
);
2841 msgqueue_initialise(&ashost
->scsi
.msgs
);
2843 acornscsi_resetcard(ashost
);
2845 ret
= scsi_add_host(host
, &ec
->dev
);
2849 scsi_scan_host(host
);
2853 free_irq(host
->irq
, ashost
);
2854 msgqueue_free(&ashost
->scsi
.msgs
);
2855 queue_free(&ashost
->queues
.disconnected
);
2856 queue_free(&ashost
->queues
.issue
);
2858 ecardm_iounmap(ec
, ashost
->fast
);
2859 ecardm_iounmap(ec
, ashost
->base
);
2860 scsi_host_put(host
);
2862 ecard_release_resources(ec
);
2867 static void acornscsi_remove(struct expansion_card
*ec
)
2869 struct Scsi_Host
*host
= ecard_get_drvdata(ec
);
2870 AS_Host
*ashost
= (AS_Host
*)host
->hostdata
;
2872 ecard_set_drvdata(ec
, NULL
);
2873 scsi_remove_host(host
);
2876 * Put card into RESET state
2878 writeb(0x80, ashost
->fast
+ PAGE_REG
);
2880 free_irq(host
->irq
, ashost
);
2882 msgqueue_free(&ashost
->scsi
.msgs
);
2883 queue_free(&ashost
->queues
.disconnected
);
2884 queue_free(&ashost
->queues
.issue
);
2885 ecardm_iounmap(ec
, ashost
->fast
);
2886 ecardm_iounmap(ec
, ashost
->base
);
2887 scsi_host_put(host
);
2888 ecard_release_resources(ec
);
2891 static const struct ecard_id acornscsi_cids
[] = {
2892 { MANU_ACORN
, PROD_ACORN_SCSI
},
2896 static struct ecard_driver acornscsi_driver
= {
2897 .probe
= acornscsi_probe
,
2898 .remove
= acornscsi_remove
,
2899 .id_table
= acornscsi_cids
,
2901 .name
= "acornscsi",
2905 static int __init
acornscsi_init(void)
2907 return ecard_register_driver(&acornscsi_driver
);
2910 static void __exit
acornscsi_exit(void)
2912 ecard_remove_driver(&acornscsi_driver
);
2915 module_init(acornscsi_init
);
2916 module_exit(acornscsi_exit
);
2918 MODULE_AUTHOR("Russell King");
2919 MODULE_DESCRIPTION("AcornSCSI driver");
2920 MODULE_LICENSE("GPL");