2 * linux/drivers/acorn/scsi/acornscsi.c
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
11 * Abandoned using the Select and Transfer command since there were
12 * some nasty races between our software and the target devices that
13 * were not easy to solve, and the device errata had a lot of entries
14 * for this command, some of them quite nasty...
17 * 26-Sep-1997 RMK Re-jigged to use the queue module.
18 * Re-coded state machine to be based on driver
19 * state not scsi state. Should be easier to debug.
20 * Added acornscsi_release to clean up properly.
21 * Updated proc/scsi reporting.
22 * 05-Oct-1997 RMK Implemented writing to SCSI devices.
23 * 06-Oct-1997 RMK Corrected small (non-serious) bug with the connect/
24 * reconnect race condition causing a warning message.
25 * 12-Oct-1997 RMK Added catch for re-entering interrupt routine.
26 * 15-Oct-1997 RMK Improved handling of commands.
27 * 27-Jun-1998 RMK Changed asm/delay.h to linux/delay.h.
28 * 13-Dec-1998 RMK Better abort code and command handling. Extra state
29 * transitions added to allow dodgy devices to work.
31 #define DEBUG_NO_WRITE 1
32 #define DEBUG_QUEUES 2
35 #define DEBUG_DISCON 16
36 #define DEBUG_CONNECT 32
37 #define DEBUG_PHASES 64
38 #define DEBUG_WRITE 128
39 #define DEBUG_LINK 256
40 #define DEBUG_MESSAGES 512
41 #define DEBUG_RESET 1024
42 #define DEBUG_ALL (DEBUG_RESET|DEBUG_MESSAGES|DEBUG_LINK|DEBUG_WRITE|\
43 DEBUG_PHASES|DEBUG_CONNECT|DEBUG_DISCON|DEBUG_ABORT|\
44 DEBUG_DMA|DEBUG_QUEUES)
46 /* DRIVER CONFIGURATION
48 * SCSI-II Tagged queue support.
50 * I don't have any SCSI devices that support it, so it is totally untested
51 * (except to make sure that it doesn't interfere with any non-tagging
52 * devices). It is not fully implemented either - what happens when a
53 * tagging device reconnects???
55 * You can tell if you have a device that supports tagged queueing my
56 * cating (eg) /proc/scsi/acornscsi/0 and see if the SCSI revision is reported
59 * Also note that CONFIG_SCSI_ACORNSCSI_TAGGED_QUEUE is normally set in the config
60 * scripts, but disabled here. Once debugged, remove the #undef, otherwise to debug,
61 * comment out the undef.
63 #undef CONFIG_SCSI_ACORNSCSI_TAGGED_QUEUE
65 * SCSI-II Linked command support.
67 * The higher level code doesn't support linked commands yet, and so the option
70 #undef CONFIG_SCSI_ACORNSCSI_LINK
72 * SCSI-II Synchronous transfer support.
76 * SDTR_SIZE - maximum number of un-acknowledged bytes (0 = off, 12 = max)
77 * SDTR_PERIOD - period of REQ signal (min=125, max=1020)
78 * DEFAULT_PERIOD - default REQ period.
81 #define SDTR_PERIOD 125
82 #define DEFAULT_PERIOD 500
85 * Debugging information
87 * DEBUG - bit mask from list above
88 * DEBUG_TARGET - is defined to the target number if you want to debug
89 * a specific target. [only recon/write/dma].
91 #define DEBUG (DEBUG_RESET|DEBUG_WRITE|DEBUG_NO_WRITE)
92 /* only allow writing to SCSI device 0 */
94 /*#define DEBUG_TARGET 2*/
96 * Select timeout time (in 10ms units)
98 * This is the timeout used between the start of selection and the WD33C93
99 * chip deciding that the device isn't responding.
101 #define TIMEOUT_TIME 10
103 * Define this if you want to have verbose explanation of SCSI
106 #undef CONFIG_ACORNSCSI_CONSTANTS
108 * Define this if you want to use the on board DMAC [don't remove this option]
109 * If not set, then use PIO mode (not currently supported).
114 * ====================================================================================
118 #define DBG(cmd,xxx...) \
119 if (cmd->device->id == DEBUG_TARGET) { \
123 #define DBG(cmd,xxx...) xxx
126 #include <linux/module.h>
127 #include <linux/kernel.h>
128 #include <linux/string.h>
129 #include <linux/signal.h>
130 #include <linux/errno.h>
131 #include <linux/proc_fs.h>
132 #include <linux/ioport.h>
133 #include <linux/blkdev.h>
134 #include <linux/delay.h>
135 #include <linux/interrupt.h>
136 #include <linux/init.h>
137 #include <linux/bitops.h>
138 #include <linux/stringify.h>
139 #include <linux/io.h>
141 #include <asm/ecard.h>
144 #include <scsi/scsi_dbg.h>
145 #include <scsi/scsi_host.h>
146 #include <scsi/scsi_transport_spi.h>
147 #include "acornscsi.h"
148 #include "msgqueue.h"
151 #include <scsi/scsicam.h>
158 #define ABORT_TAG 0xd
160 #error "Yippee! ABORT TAG is now defined! Remove this error!"
163 #ifdef CONFIG_SCSI_ACORNSCSI_LINK
164 #error SCSI2 LINKed commands not supported (yet)!
169 * DMAC setup parameters
171 #define INIT_DEVCON0 (DEVCON0_RQL|DEVCON0_EXW|DEVCON0_CMP)
172 #define INIT_DEVCON1 (DEVCON1_BHLD)
173 #define DMAC_READ (MODECON_READ)
174 #define DMAC_WRITE (MODECON_WRITE)
175 #define INIT_SBICDMA (CTRL_DMABURST)
177 #define scsi_xferred have_data_in
180 * Size of on-board DMA buffer
182 #define DMAC_BUFFER_SIZE 65536
185 #define STATUS_BUFFER_TO_PRINT 24
187 unsigned int sdtr_period
= SDTR_PERIOD
;
188 unsigned int sdtr_size
= SDTR_SIZE
;
190 static void acornscsi_done(AS_Host
*host
, struct scsi_cmnd
**SCpntp
,
191 unsigned int result
);
192 static int acornscsi_reconnect_finish(AS_Host
*host
);
193 static void acornscsi_dma_cleanup(AS_Host
*host
);
194 static void acornscsi_abortcmd(AS_Host
*host
, unsigned char tag
);
196 /* ====================================================================================
200 /* Offsets from MEMC base */
201 #define SBIC_REGIDX 0x2000
202 #define SBIC_REGVAL 0x2004
203 #define DMAC_OFFSET 0x3000
205 /* Offsets from FAST IOC base */
206 #define INT_REG 0x2000
207 #define PAGE_REG 0x3000
209 static inline void sbic_arm_write(AS_Host
*host
, unsigned int reg
, unsigned int value
)
211 writeb(reg
, host
->base
+ SBIC_REGIDX
);
212 writeb(value
, host
->base
+ SBIC_REGVAL
);
215 static inline int sbic_arm_read(AS_Host
*host
, unsigned int reg
)
218 return readl(host
->base
+ SBIC_REGIDX
) & 255;
219 writeb(reg
, host
->base
+ SBIC_REGIDX
);
220 return readl(host
->base
+ SBIC_REGVAL
) & 255;
223 #define sbic_arm_writenext(host, val) writeb((val), (host)->base + SBIC_REGVAL)
224 #define sbic_arm_readnext(host) readb((host)->base + SBIC_REGVAL)
227 #define dmac_read(host,reg) \
228 readb((host)->base + DMAC_OFFSET + ((reg) << 2))
230 #define dmac_write(host,reg,value) \
231 ({ writeb((value), (host)->base + DMAC_OFFSET + ((reg) << 2)); })
233 #define dmac_clearintr(host) writeb(0, (host)->fast + INT_REG)
235 static inline unsigned int dmac_address(AS_Host
*host
)
237 return dmac_read(host
, DMAC_TXADRHI
) << 16 |
238 dmac_read(host
, DMAC_TXADRMD
) << 8 |
239 dmac_read(host
, DMAC_TXADRLO
);
243 void acornscsi_dumpdma(AS_Host
*host
, char *where
)
245 unsigned int mode
, addr
, len
;
247 mode
= dmac_read(host
, DMAC_MODECON
);
248 addr
= dmac_address(host
);
249 len
= dmac_read(host
, DMAC_TXCNTHI
) << 8 |
250 dmac_read(host
, DMAC_TXCNTLO
);
252 printk("scsi%d: %s: DMAC %02x @%06x+%04x msk %02x, ",
253 host
->host
->host_no
, where
,
254 mode
, addr
, (len
+ 1) & 0xffff,
255 dmac_read(host
, DMAC_MASKREG
));
257 printk("DMA @%06x, ", host
->dma
.start_addr
);
258 printk("BH @%p +%04x, ", host
->scsi
.SCp
.ptr
,
259 host
->scsi
.SCp
.this_residual
);
260 printk("DT @+%04x ST @+%04x", host
->dma
.transferred
,
261 host
->scsi
.SCp
.scsi_xferred
);
267 unsigned long acornscsi_sbic_xfcount(AS_Host
*host
)
269 unsigned long length
;
271 length
= sbic_arm_read(host
, SBIC_TRANSCNTH
) << 16;
272 length
|= sbic_arm_readnext(host
) << 8;
273 length
|= sbic_arm_readnext(host
);
279 acornscsi_sbic_wait(AS_Host
*host
, int stat_mask
, int stat
, int timeout
, char *msg
)
284 asr
= sbic_arm_read(host
, SBIC_ASR
);
286 if ((asr
& stat_mask
) == stat
)
292 printk("scsi%d: timeout while %s\n", host
->host
->host_no
, msg
);
298 int acornscsi_sbic_issuecmd(AS_Host
*host
, int command
)
300 if (acornscsi_sbic_wait(host
, ASR_CIP
, 0, 1000, "issuing command"))
303 sbic_arm_write(host
, SBIC_CMND
, command
);
309 acornscsi_csdelay(unsigned int cs
)
311 unsigned long target_jiffies
, flags
;
313 target_jiffies
= jiffies
+ 1 + cs
* HZ
/ 100;
315 local_save_flags(flags
);
318 while (time_before(jiffies
, target_jiffies
)) barrier();
320 local_irq_restore(flags
);
324 void acornscsi_resetcard(AS_Host
*host
)
326 unsigned int i
, timeout
;
328 /* assert reset line */
329 host
->card
.page_reg
= 0x80;
330 writeb(host
->card
.page_reg
, host
->fast
+ PAGE_REG
);
332 /* wait 3 cs. SCSI standard says 25ms. */
333 acornscsi_csdelay(3);
335 host
->card
.page_reg
= 0;
336 writeb(host
->card
.page_reg
, host
->fast
+ PAGE_REG
);
339 * Should get a reset from the card
343 if (readb(host
->fast
+ INT_REG
) & 8)
349 printk("scsi%d: timeout while resetting card\n",
350 host
->host
->host_no
);
352 sbic_arm_read(host
, SBIC_ASR
);
353 sbic_arm_read(host
, SBIC_SSR
);
355 /* setup sbic - WD33C93A */
356 sbic_arm_write(host
, SBIC_OWNID
, OWNID_EAF
| host
->host
->this_id
);
357 sbic_arm_write(host
, SBIC_CMND
, CMND_RESET
);
360 * Command should cause a reset interrupt
364 if (readb(host
->fast
+ INT_REG
) & 8)
370 printk("scsi%d: timeout while resetting card\n",
371 host
->host
->host_no
);
373 sbic_arm_read(host
, SBIC_ASR
);
374 if (sbic_arm_read(host
, SBIC_SSR
) != 0x01)
375 printk(KERN_CRIT
"scsi%d: WD33C93A didn't give enhanced reset interrupt\n",
376 host
->host
->host_no
);
378 sbic_arm_write(host
, SBIC_CTRL
, INIT_SBICDMA
| CTRL_IDI
);
379 sbic_arm_write(host
, SBIC_TIMEOUT
, TIMEOUT_TIME
);
380 sbic_arm_write(host
, SBIC_SYNCHTRANSFER
, SYNCHTRANSFER_2DBA
);
381 sbic_arm_write(host
, SBIC_SOURCEID
, SOURCEID_ER
| SOURCEID_DSP
);
383 host
->card
.page_reg
= 0x40;
384 writeb(host
->card
.page_reg
, host
->fast
+ PAGE_REG
);
386 /* setup dmac - uPC71071 */
387 dmac_write(host
, DMAC_INIT
, 0);
389 dmac_write(host
, DMAC_INIT
, INIT_8BIT
);
390 dmac_write(host
, DMAC_CHANNEL
, CHANNEL_0
);
391 dmac_write(host
, DMAC_DEVCON0
, INIT_DEVCON0
);
392 dmac_write(host
, DMAC_DEVCON1
, INIT_DEVCON1
);
396 host
->scsi
.phase
= PHASE_IDLE
;
397 host
->scsi
.disconnectable
= 0;
399 memset(host
->busyluns
, 0, sizeof(host
->busyluns
));
401 for (i
= 0; i
< 8; i
++) {
402 host
->device
[i
].sync_state
= SYNC_NEGOCIATE
;
403 host
->device
[i
].disconnect_ok
= 1;
406 /* wait 25 cs. SCSI standard says 250ms. */
407 acornscsi_csdelay(25);
410 /*=============================================================================================
411 * Utility routines (eg. debug)
413 #ifdef CONFIG_ACORNSCSI_CONSTANTS
414 static char *acornscsi_interrupttype
[] = {
415 "rst", "suc", "p/a", "3",
416 "term", "5", "6", "7",
417 "serv", "9", "a", "b",
421 static signed char acornscsi_map
[] = {
422 0, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
423 -1, 2, -1, -1, -1, -1, 3, -1, 4, 5, 6, 7, 8, 9, 10, 11,
424 12, 13, 14, -1, -1, -1, -1, -1, 4, 5, 6, 7, 8, 9, 10, 11,
425 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
426 15, 16, 17, 18, 19, -1, -1, 20, 4, 5, 6, 7, 8, 9, 10, 11,
427 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
428 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
429 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
430 21, 22, -1, -1, -1, 23, -1, -1, 4, 5, 6, 7, 8, 9, 10, 11,
431 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
432 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
433 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
434 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
435 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
436 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
437 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
440 static char *acornscsi_interruptcode
[] = {
442 "reset - normal mode", /* 00 */
443 "reset - advanced mode", /* 01 */
458 "/ACK asserted", /* 20 */
459 "save-data-ptr", /* 21 */
464 "unexpected disconnect", /* 41 */
465 "sel timeout", /* 42 */
467 "P err+ATN", /* 44 */
468 "bad status byte", /* 47 */
471 "resel, no id", /* 80 */
477 void print_scsi_status(unsigned int ssr
)
479 if (acornscsi_map
[ssr
] != -1)
481 acornscsi_interrupttype
[(ssr
>> 4)],
482 acornscsi_interruptcode
[acornscsi_map
[ssr
]]);
484 printk("%X:%X", ssr
>> 4, ssr
& 0x0f);
489 void print_sbic_status(int asr
, int ssr
, int cmdphase
)
491 #ifdef CONFIG_ACORNSCSI_CONSTANTS
492 printk("sbic: %c%c%c%c%c%c ",
493 asr
& ASR_INT
? 'I' : 'i',
494 asr
& ASR_LCI
? 'L' : 'l',
495 asr
& ASR_BSY
? 'B' : 'b',
496 asr
& ASR_CIP
? 'C' : 'c',
497 asr
& ASR_PE
? 'P' : 'p',
498 asr
& ASR_DBR
? 'D' : 'd');
500 print_scsi_status(ssr
);
501 printk(" ph %02X\n", cmdphase
);
503 printk("sbic: %02X scsi: %X:%X ph: %02X\n",
504 asr
, (ssr
& 0xf0)>>4, ssr
& 0x0f, cmdphase
);
509 acornscsi_dumplogline(AS_Host
*host
, int target
, int line
)
514 ptr
= host
->status_ptr
[target
] - STATUS_BUFFER_TO_PRINT
;
516 ptr
+= STATUS_BUFFER_SIZE
;
518 printk("%c: %3s:", target
== 8 ? 'H' : '0' + target
,
519 line
== 0 ? "ph" : line
== 1 ? "ssr" : "int");
521 prev
= host
->status
[target
][ptr
].when
;
523 for (; ptr
!= host
->status_ptr
[target
]; ptr
= (ptr
+ 1) & (STATUS_BUFFER_SIZE
- 1)) {
524 unsigned long time_diff
;
526 if (!host
->status
[target
][ptr
].when
)
531 printk("%c%02X", host
->status
[target
][ptr
].irq
? '-' : ' ',
532 host
->status
[target
][ptr
].ph
);
536 printk(" %02X", host
->status
[target
][ptr
].ssr
);
540 time_diff
= host
->status
[target
][ptr
].when
- prev
;
541 prev
= host
->status
[target
][ptr
].when
;
544 else if (time_diff
>= 100)
547 printk(" %02ld", time_diff
);
556 void acornscsi_dumplog(AS_Host
*host
, int target
)
559 acornscsi_dumplogline(host
, target
, 0);
560 acornscsi_dumplogline(host
, target
, 1);
561 acornscsi_dumplogline(host
, target
, 2);
571 char acornscsi_target(AS_Host
*host
)
574 return '0' + host
->SCpnt
->device
->id
;
579 * Prototype: cmdtype_t acornscsi_cmdtype(int command)
580 * Purpose : differentiate READ from WRITE from other commands
581 * Params : command - command to interpret
582 * Returns : CMD_READ - command reads data,
583 * CMD_WRITE - command writes data,
584 * CMD_MISC - everything else
587 cmdtype_t
acornscsi_cmdtype(int command
)
590 case WRITE_6
: case WRITE_10
: case WRITE_12
:
592 case READ_6
: case READ_10
: case READ_12
:
600 * Prototype: int acornscsi_datadirection(int command)
601 * Purpose : differentiate between commands that have a DATA IN phase
602 * and a DATA OUT phase
603 * Params : command - command to interpret
604 * Returns : DATADIR_OUT - data out phase expected
605 * DATADIR_IN - data in phase expected
608 datadir_t
acornscsi_datadirection(int command
)
611 case CHANGE_DEFINITION
: case COMPARE
: case COPY
:
612 case COPY_VERIFY
: case LOG_SELECT
: case MODE_SELECT
:
613 case MODE_SELECT_10
: case SEND_DIAGNOSTIC
: case WRITE_BUFFER
:
614 case FORMAT_UNIT
: case REASSIGN_BLOCKS
: case RESERVE
:
615 case SEARCH_EQUAL
: case SEARCH_HIGH
: case SEARCH_LOW
:
616 case WRITE_6
: case WRITE_10
: case WRITE_VERIFY
:
617 case UPDATE_BLOCK
: case WRITE_LONG
: case WRITE_SAME
:
618 case SEARCH_HIGH_12
: case SEARCH_EQUAL_12
: case SEARCH_LOW_12
:
619 case WRITE_12
: case WRITE_VERIFY_12
: case SET_WINDOW
:
620 case MEDIUM_SCAN
: case SEND_VOLUME_TAG
: case 0xea:
628 * Purpose : provide values for synchronous transfers with 33C93.
629 * Copyright: Copyright (c) 1996 John Shifflett, GeoLog Consulting
630 * Modified by Russell King for 8MHz WD33C93A
632 static struct sync_xfer_tbl
{
633 unsigned int period_ns
;
634 unsigned char reg_value
;
635 } sync_xfer_table
[] = {
636 { 1, 0x20 }, { 249, 0x20 }, { 374, 0x30 },
637 { 499, 0x40 }, { 624, 0x50 }, { 749, 0x60 },
638 { 874, 0x70 }, { 999, 0x00 }, { 0, 0 }
642 * Prototype: int acornscsi_getperiod(unsigned char syncxfer)
643 * Purpose : period for the synchronous transfer setting
644 * Params : syncxfer SYNCXFER register value
645 * Returns : period in ns.
648 int acornscsi_getperiod(unsigned char syncxfer
)
653 if (syncxfer
== 0x10)
656 for (i
= 1; sync_xfer_table
[i
].period_ns
; i
++)
657 if (syncxfer
== sync_xfer_table
[i
].reg_value
)
658 return sync_xfer_table
[i
].period_ns
;
663 * Prototype: int round_period(unsigned int period)
664 * Purpose : return index into above table for a required REQ period
665 * Params : period - time (ns) for REQ
666 * Returns : table index
667 * Copyright: Copyright (c) 1996 John Shifflett, GeoLog Consulting
670 int round_period(unsigned int period
)
674 for (i
= 1; sync_xfer_table
[i
].period_ns
; i
++) {
675 if ((period
<= sync_xfer_table
[i
].period_ns
) &&
676 (period
> sync_xfer_table
[i
- 1].period_ns
))
683 * Prototype: unsigned char calc_sync_xfer(unsigned int period, unsigned int offset)
684 * Purpose : calculate value for 33c93s SYNC register
685 * Params : period - time (ns) for REQ
686 * offset - offset in bytes between REQ/ACK
687 * Returns : value for SYNC register
688 * Copyright: Copyright (c) 1996 John Shifflett, GeoLog Consulting
691 unsigned char calc_sync_xfer(unsigned int period
, unsigned int offset
)
693 return sync_xfer_table
[round_period(period
)].reg_value
|
694 ((offset
< SDTR_SIZE
) ? offset
: SDTR_SIZE
);
697 /* ====================================================================================
701 * Function: acornscsi_kick(AS_Host *host)
702 * Purpose : kick next command to interface
703 * Params : host - host to send command to
704 * Returns : INTR_IDLE if idle, otherwise INTR_PROCESSING
705 * Notes : interrupts are always disabled!
708 intr_ret_t
acornscsi_kick(AS_Host
*host
)
711 struct scsi_cmnd
*SCpnt
;
713 /* first check to see if a command is waiting to be executed */
714 SCpnt
= host
->origSCpnt
;
715 host
->origSCpnt
= NULL
;
717 /* retrieve next command */
719 SCpnt
= queue_remove_exclude(&host
->queues
.issue
, host
->busyluns
);
726 if (host
->scsi
.disconnectable
&& host
->SCpnt
) {
727 queue_add_cmd_tail(&host
->queues
.disconnected
, host
->SCpnt
);
728 host
->scsi
.disconnectable
= 0;
729 #if (DEBUG & (DEBUG_QUEUES|DEBUG_DISCON))
730 DBG(host
->SCpnt
, printk("scsi%d.%c: moved command to disconnected queue\n",
731 host
->host
->host_no
, acornscsi_target(host
)));
737 * If we have an interrupt pending, then we may have been reselected.
738 * In this case, we don't want to write to the registers
740 if (!(sbic_arm_read(host
, SBIC_ASR
) & (ASR_INT
|ASR_BSY
|ASR_CIP
))) {
741 sbic_arm_write(host
, SBIC_DESTID
, SCpnt
->device
->id
);
742 sbic_arm_write(host
, SBIC_CMND
, CMND_SELWITHATN
);
746 * claim host busy - all of these must happen atomically wrt
747 * our interrupt routine. Failure means command loss.
749 host
->scsi
.phase
= PHASE_CONNECTING
;
751 host
->scsi
.SCp
= SCpnt
->SCp
;
752 host
->dma
.xfer_setup
= 0;
753 host
->dma
.xfer_required
= 0;
754 host
->dma
.xfer_done
= 0;
756 #if (DEBUG & (DEBUG_ABORT|DEBUG_CONNECT))
757 DBG(SCpnt
,printk("scsi%d.%c: starting cmd %02X\n",
758 host
->host
->host_no
, '0' + SCpnt
->device
->id
,
763 #ifdef CONFIG_SCSI_ACORNSCSI_TAGGED_QUEUE
765 * tagged queueing - allocate a new tag to this command
767 if (SCpnt
->device
->simple_tags
) {
768 SCpnt
->device
->current_tag
+= 1;
769 if (SCpnt
->device
->current_tag
== 0)
770 SCpnt
->device
->current_tag
= 1;
771 SCpnt
->tag
= SCpnt
->device
->current_tag
;
774 set_bit(SCpnt
->device
->id
* 8 + SCpnt
->device
->lun
, host
->busyluns
);
776 host
->stats
.removes
+= 1;
778 switch (acornscsi_cmdtype(SCpnt
->cmnd
[0])) {
780 host
->stats
.writes
+= 1;
783 host
->stats
.reads
+= 1;
786 host
->stats
.miscs
+= 1;
791 return INTR_PROCESSING
;
795 * Function: void acornscsi_done(AS_Host *host, struct scsi_cmnd **SCpntp, unsigned int result)
796 * Purpose : complete processing for command
797 * Params : host - interface that completed
798 * result - driver byte of result
800 static void acornscsi_done(AS_Host
*host
, struct scsi_cmnd
**SCpntp
,
803 struct scsi_cmnd
*SCpnt
= *SCpntp
;
806 sbic_arm_write(host
, SBIC_SOURCEID
, SOURCEID_ER
| SOURCEID_DSP
);
808 host
->stats
.fins
+= 1;
813 acornscsi_dma_cleanup(host
);
815 SCpnt
->result
= result
<< 16 | host
->scsi
.SCp
.Message
<< 8 | host
->scsi
.SCp
.Status
;
818 * In theory, this should not happen. In practice, it seems to.
819 * Only trigger an error if the device attempts to report all happy
820 * but with untransferred buffers... If we don't do something, then
821 * data loss will occur. Should we check SCpnt->underflow here?
822 * It doesn't appear to be set to something meaningful by the higher
823 * levels all the time.
825 if (result
== DID_OK
) {
828 if (SCpnt
->underflow
== 0) {
829 if (host
->scsi
.SCp
.ptr
&&
830 acornscsi_cmdtype(SCpnt
->cmnd
[0]) != CMD_MISC
)
833 if (host
->scsi
.SCp
.scsi_xferred
< SCpnt
->underflow
||
834 host
->scsi
.SCp
.scsi_xferred
!= host
->dma
.transferred
)
838 /* ANSI standard says: (SCSI-2 Rev 10c Sect 5.6.6)
839 * Targets which break data transfers into multiple
840 * connections shall end each successful connection
841 * (except possibly the last) with a SAVE DATA
842 * POINTER - DISCONNECT message sequence.
844 * This makes it difficult to ensure that a transfer has
845 * completed. If we reach the end of a transfer during
846 * the command, then we can only have finished the transfer.
847 * therefore, if we seem to have some data remaining, this
850 if (host
->dma
.xfer_done
)
854 switch (status_byte(SCpnt
->result
)) {
855 case CHECK_CONDITION
:
856 case COMMAND_TERMINATED
:
859 case RESERVATION_CONFLICT
:
863 printk(KERN_ERR
"scsi%d.H: incomplete data transfer detected: result=%08X command=",
864 host
->host
->host_no
, SCpnt
->result
);
865 __scsi_print_command(SCpnt
->cmnd
);
866 acornscsi_dumpdma(host
, "done");
867 acornscsi_dumplog(host
, SCpnt
->device
->id
);
868 SCpnt
->result
&= 0xffff;
869 SCpnt
->result
|= DID_ERROR
<< 16;
874 if (!SCpnt
->scsi_done
)
875 panic("scsi%d.H: null scsi_done function in acornscsi_done", host
->host
->host_no
);
877 clear_bit(SCpnt
->device
->id
* 8 + SCpnt
->device
->lun
, host
->busyluns
);
879 SCpnt
->scsi_done(SCpnt
);
881 printk("scsi%d: null command in acornscsi_done", host
->host
->host_no
);
883 host
->scsi
.phase
= PHASE_IDLE
;
886 /* ====================================================================================
890 * Purpose : update SCSI Data Pointer
891 * Notes : this will only be one SG entry or less
894 void acornscsi_data_updateptr(AS_Host
*host
, struct scsi_pointer
*SCp
, unsigned int length
)
897 SCp
->this_residual
-= length
;
899 if (SCp
->this_residual
== 0 && next_SCp(SCp
) == 0)
900 host
->dma
.xfer_done
= 1;
904 * Prototype: void acornscsi_data_read(AS_Host *host, char *ptr,
905 * unsigned int start_addr, unsigned int length)
906 * Purpose : read data from DMA RAM
907 * Params : host - host to transfer from
909 * start_addr - host mem address
910 * length - number of bytes to transfer
911 * Notes : this will only be one SG entry or less
914 void acornscsi_data_read(AS_Host
*host
, char *ptr
,
915 unsigned int start_addr
, unsigned int length
)
917 extern void __acornscsi_in(void __iomem
*, char *buf
, int len
);
918 unsigned int page
, offset
, len
= length
;
920 page
= (start_addr
>> 12);
921 offset
= start_addr
& ((1 << 12) - 1);
923 writeb((page
& 0x3f) | host
->card
.page_reg
, host
->fast
+ PAGE_REG
);
926 unsigned int this_len
;
928 if (len
+ offset
> (1 << 12))
929 this_len
= (1 << 12) - offset
;
933 __acornscsi_in(host
->base
+ (offset
<< 1), ptr
, this_len
);
939 if (offset
== (1 << 12)) {
942 writeb((page
& 0x3f) | host
->card
.page_reg
, host
->fast
+ PAGE_REG
);
945 writeb(host
->card
.page_reg
, host
->fast
+ PAGE_REG
);
949 * Prototype: void acornscsi_data_write(AS_Host *host, char *ptr,
950 * unsigned int start_addr, unsigned int length)
951 * Purpose : write data to DMA RAM
952 * Params : host - host to transfer from
954 * start_addr - host mem address
955 * length - number of bytes to transfer
956 * Notes : this will only be one SG entry or less
959 void acornscsi_data_write(AS_Host
*host
, char *ptr
,
960 unsigned int start_addr
, unsigned int length
)
962 extern void __acornscsi_out(void __iomem
*, char *buf
, int len
);
963 unsigned int page
, offset
, len
= length
;
965 page
= (start_addr
>> 12);
966 offset
= start_addr
& ((1 << 12) - 1);
968 writeb((page
& 0x3f) | host
->card
.page_reg
, host
->fast
+ PAGE_REG
);
971 unsigned int this_len
;
973 if (len
+ offset
> (1 << 12))
974 this_len
= (1 << 12) - offset
;
978 __acornscsi_out(host
->base
+ (offset
<< 1), ptr
, this_len
);
984 if (offset
== (1 << 12)) {
987 writeb((page
& 0x3f) | host
->card
.page_reg
, host
->fast
+ PAGE_REG
);
990 writeb(host
->card
.page_reg
, host
->fast
+ PAGE_REG
);
993 /* =========================================================================================
994 * On-board DMA routines
998 * Prototype: void acornscsi_dmastop(AS_Host *host)
999 * Purpose : stop all DMA
1000 * Params : host - host on which to stop DMA
1001 * Notes : This is called when leaving DATA IN/OUT phase,
1002 * or when interface is RESET
1005 void acornscsi_dma_stop(AS_Host
*host
)
1007 dmac_write(host
, DMAC_MASKREG
, MASK_ON
);
1008 dmac_clearintr(host
);
1010 #if (DEBUG & DEBUG_DMA)
1011 DBG(host
->SCpnt
, acornscsi_dumpdma(host
, "stop"));
1016 * Function: void acornscsi_dma_setup(AS_Host *host, dmadir_t direction)
1017 * Purpose : setup DMA controller for data transfer
1018 * Params : host - host to setup
1019 * direction - data transfer direction
1020 * Notes : This is called when entering DATA I/O phase, not
1021 * while we're in a DATA I/O phase
1024 void acornscsi_dma_setup(AS_Host
*host
, dmadir_t direction
)
1026 unsigned int address
, length
, mode
;
1028 host
->dma
.direction
= direction
;
1030 dmac_write(host
, DMAC_MASKREG
, MASK_ON
);
1032 if (direction
== DMA_OUT
) {
1033 #if (DEBUG & DEBUG_NO_WRITE)
1034 if (NO_WRITE
& (1 << host
->SCpnt
->device
->id
)) {
1035 printk(KERN_CRIT
"scsi%d.%c: I can't handle DMA_OUT!\n",
1036 host
->host
->host_no
, acornscsi_target(host
));
1045 * Allocate some buffer space, limited to half the buffer size
1047 length
= min_t(unsigned int, host
->scsi
.SCp
.this_residual
, DMAC_BUFFER_SIZE
/ 2);
1049 host
->dma
.start_addr
= address
= host
->dma
.free_addr
;
1050 host
->dma
.free_addr
= (host
->dma
.free_addr
+ length
) &
1051 (DMAC_BUFFER_SIZE
- 1);
1054 * Transfer data to DMA memory
1056 if (direction
== DMA_OUT
)
1057 acornscsi_data_write(host
, host
->scsi
.SCp
.ptr
, host
->dma
.start_addr
,
1061 dmac_write(host
, DMAC_TXCNTLO
, length
);
1062 dmac_write(host
, DMAC_TXCNTHI
, length
>> 8);
1063 dmac_write(host
, DMAC_TXADRLO
, address
);
1064 dmac_write(host
, DMAC_TXADRMD
, address
>> 8);
1065 dmac_write(host
, DMAC_TXADRHI
, 0);
1066 dmac_write(host
, DMAC_MODECON
, mode
);
1067 dmac_write(host
, DMAC_MASKREG
, MASK_OFF
);
1069 #if (DEBUG & DEBUG_DMA)
1070 DBG(host
->SCpnt
, acornscsi_dumpdma(host
, "strt"));
1072 host
->dma
.xfer_setup
= 1;
1077 * Function: void acornscsi_dma_cleanup(AS_Host *host)
1078 * Purpose : ensure that all DMA transfers are up-to-date & host->scsi.SCp is correct
1079 * Params : host - host to finish
1080 * Notes : This is called when a command is:
1081 * terminating, RESTORE_POINTERS, SAVE_POINTERS, DISCONECT
1082 * : This must not return until all transfers are completed.
1085 void acornscsi_dma_cleanup(AS_Host
*host
)
1087 dmac_write(host
, DMAC_MASKREG
, MASK_ON
);
1088 dmac_clearintr(host
);
1091 * Check for a pending transfer
1093 if (host
->dma
.xfer_required
) {
1094 host
->dma
.xfer_required
= 0;
1095 if (host
->dma
.direction
== DMA_IN
)
1096 acornscsi_data_read(host
, host
->dma
.xfer_ptr
,
1097 host
->dma
.xfer_start
, host
->dma
.xfer_length
);
1101 * Has a transfer been setup?
1103 if (host
->dma
.xfer_setup
) {
1104 unsigned int transferred
;
1106 host
->dma
.xfer_setup
= 0;
1108 #if (DEBUG & DEBUG_DMA)
1109 DBG(host
->SCpnt
, acornscsi_dumpdma(host
, "cupi"));
1113 * Calculate number of bytes transferred from DMA.
1115 transferred
= dmac_address(host
) - host
->dma
.start_addr
;
1116 host
->dma
.transferred
+= transferred
;
1118 if (host
->dma
.direction
== DMA_IN
)
1119 acornscsi_data_read(host
, host
->scsi
.SCp
.ptr
,
1120 host
->dma
.start_addr
, transferred
);
1123 * Update SCSI pointers
1125 acornscsi_data_updateptr(host
, &host
->scsi
.SCp
, transferred
);
1126 #if (DEBUG & DEBUG_DMA)
1127 DBG(host
->SCpnt
, acornscsi_dumpdma(host
, "cupo"));
1133 * Function: void acornscsi_dmacintr(AS_Host *host)
1134 * Purpose : handle interrupts from DMAC device
1135 * Params : host - host to process
1136 * Notes : If reading, we schedule the read to main memory &
1137 * allow the transfer to continue.
1138 * : If writing, we fill the onboard DMA memory from main
1140 * : Called whenever DMAC finished it's current transfer.
1143 void acornscsi_dma_intr(AS_Host
*host
)
1145 unsigned int address
, length
, transferred
;
1147 #if (DEBUG & DEBUG_DMA)
1148 DBG(host
->SCpnt
, acornscsi_dumpdma(host
, "inti"));
1151 dmac_write(host
, DMAC_MASKREG
, MASK_ON
);
1152 dmac_clearintr(host
);
1155 * Calculate amount transferred via DMA
1157 transferred
= dmac_address(host
) - host
->dma
.start_addr
;
1158 host
->dma
.transferred
+= transferred
;
1161 * Schedule DMA transfer off board
1163 if (host
->dma
.direction
== DMA_IN
) {
1164 host
->dma
.xfer_start
= host
->dma
.start_addr
;
1165 host
->dma
.xfer_length
= transferred
;
1166 host
->dma
.xfer_ptr
= host
->scsi
.SCp
.ptr
;
1167 host
->dma
.xfer_required
= 1;
1170 acornscsi_data_updateptr(host
, &host
->scsi
.SCp
, transferred
);
1173 * Allocate some buffer space, limited to half the on-board RAM size
1175 length
= min_t(unsigned int, host
->scsi
.SCp
.this_residual
, DMAC_BUFFER_SIZE
/ 2);
1177 host
->dma
.start_addr
= address
= host
->dma
.free_addr
;
1178 host
->dma
.free_addr
= (host
->dma
.free_addr
+ length
) &
1179 (DMAC_BUFFER_SIZE
- 1);
1182 * Transfer data to DMA memory
1184 if (host
->dma
.direction
== DMA_OUT
)
1185 acornscsi_data_write(host
, host
->scsi
.SCp
.ptr
, host
->dma
.start_addr
,
1189 dmac_write(host
, DMAC_TXCNTLO
, length
);
1190 dmac_write(host
, DMAC_TXCNTHI
, length
>> 8);
1191 dmac_write(host
, DMAC_TXADRLO
, address
);
1192 dmac_write(host
, DMAC_TXADRMD
, address
>> 8);
1193 dmac_write(host
, DMAC_TXADRHI
, 0);
1194 dmac_write(host
, DMAC_MASKREG
, MASK_OFF
);
1196 #if (DEBUG & DEBUG_DMA)
1197 DBG(host
->SCpnt
, acornscsi_dumpdma(host
, "into"));
1200 host
->dma
.xfer_setup
= 0;
1203 * If the interface still wants more, then this is an error.
1204 * We give it another byte, but we also attempt to raise an
1205 * attention condition. We continue giving one byte until
1206 * the device recognises the attention.
1208 if (dmac_read(host
, DMAC_STATUS
) & STATUS_RQ0
) {
1209 acornscsi_abortcmd(host
, host
->SCpnt
->tag
);
1211 dmac_write(host
, DMAC_TXCNTLO
, 0);
1212 dmac_write(host
, DMAC_TXCNTHI
, 0);
1213 dmac_write(host
, DMAC_TXADRLO
, 0);
1214 dmac_write(host
, DMAC_TXADRMD
, 0);
1215 dmac_write(host
, DMAC_TXADRHI
, 0);
1216 dmac_write(host
, DMAC_MASKREG
, MASK_OFF
);
1223 * Function: void acornscsi_dma_xfer(AS_Host *host)
1224 * Purpose : transfer data between AcornSCSI and memory
1225 * Params : host - host to process
1228 void acornscsi_dma_xfer(AS_Host
*host
)
1230 host
->dma
.xfer_required
= 0;
1232 if (host
->dma
.direction
== DMA_IN
)
1233 acornscsi_data_read(host
, host
->dma
.xfer_ptr
,
1234 host
->dma
.xfer_start
, host
->dma
.xfer_length
);
1238 * Function: void acornscsi_dma_adjust(AS_Host *host)
1239 * Purpose : adjust DMA pointers & count for bytes transferred to
1240 * SBIC but not SCSI bus.
1241 * Params : host - host to adjust DMA count for
1244 void acornscsi_dma_adjust(AS_Host
*host
)
1246 if (host
->dma
.xfer_setup
) {
1247 signed long transferred
;
1248 #if (DEBUG & (DEBUG_DMA|DEBUG_WRITE))
1249 DBG(host
->SCpnt
, acornscsi_dumpdma(host
, "adji"));
1252 * Calculate correct DMA address - DMA is ahead of SCSI bus while
1254 * host->scsi.SCp.scsi_xferred is the number of bytes
1255 * actually transferred to/from the SCSI bus.
1256 * host->dma.transferred is the number of bytes transferred
1257 * over DMA since host->dma.start_addr was last set.
1259 * real_dma_addr = host->dma.start_addr + host->scsi.SCp.scsi_xferred
1260 * - host->dma.transferred
1262 transferred
= host
->scsi
.SCp
.scsi_xferred
- host
->dma
.transferred
;
1263 if (transferred
< 0)
1264 printk("scsi%d.%c: Ack! DMA write correction %ld < 0!\n",
1265 host
->host
->host_no
, acornscsi_target(host
), transferred
);
1266 else if (transferred
== 0)
1267 host
->dma
.xfer_setup
= 0;
1269 transferred
+= host
->dma
.start_addr
;
1270 dmac_write(host
, DMAC_TXADRLO
, transferred
);
1271 dmac_write(host
, DMAC_TXADRMD
, transferred
>> 8);
1272 dmac_write(host
, DMAC_TXADRHI
, transferred
>> 16);
1273 #if (DEBUG & (DEBUG_DMA|DEBUG_WRITE))
1274 DBG(host
->SCpnt
, acornscsi_dumpdma(host
, "adjo"));
1281 /* =========================================================================================
1285 acornscsi_write_pio(AS_Host
*host
, char *bytes
, int *ptr
, int len
, unsigned int max_timeout
)
1287 unsigned int asr
, timeout
= max_timeout
;
1290 while (my_ptr
< len
) {
1291 asr
= sbic_arm_read(host
, SBIC_ASR
);
1293 if (asr
& ASR_DBR
) {
1294 timeout
= max_timeout
;
1296 sbic_arm_write(host
, SBIC_DATA
, bytes
[my_ptr
++]);
1297 } else if (asr
& ASR_INT
)
1299 else if (--timeout
== 0)
1306 return (timeout
== 0) ? -1 : 0;
1310 * Function: void acornscsi_sendcommand(AS_Host *host)
1311 * Purpose : send a command to a target
1312 * Params : host - host which is connected to target
1315 acornscsi_sendcommand(AS_Host
*host
)
1317 struct scsi_cmnd
*SCpnt
= host
->SCpnt
;
1319 sbic_arm_write(host
, SBIC_TRANSCNTH
, 0);
1320 sbic_arm_writenext(host
, 0);
1321 sbic_arm_writenext(host
, SCpnt
->cmd_len
- host
->scsi
.SCp
.sent_command
);
1323 acornscsi_sbic_issuecmd(host
, CMND_XFERINFO
);
1325 if (acornscsi_write_pio(host
, SCpnt
->cmnd
,
1326 (int *)&host
->scsi
.SCp
.sent_command
, SCpnt
->cmd_len
, 1000000))
1327 printk("scsi%d: timeout while sending command\n", host
->host
->host_no
);
1329 host
->scsi
.phase
= PHASE_COMMAND
;
1333 void acornscsi_sendmessage(AS_Host
*host
)
1335 unsigned int message_length
= msgqueue_msglength(&host
->scsi
.msgs
);
1337 struct message
*msg
;
1339 #if (DEBUG & DEBUG_MESSAGES)
1340 printk("scsi%d.%c: sending message ",
1341 host
->host
->host_no
, acornscsi_target(host
));
1344 switch (message_length
) {
1346 acornscsi_sbic_issuecmd(host
, CMND_XFERINFO
| CMND_SBT
);
1348 acornscsi_sbic_wait(host
, ASR_DBR
, ASR_DBR
, 1000, "sending message 1");
1350 sbic_arm_write(host
, SBIC_DATA
, NOP
);
1352 host
->scsi
.last_message
= NOP
;
1353 #if (DEBUG & DEBUG_MESSAGES)
1359 acornscsi_sbic_issuecmd(host
, CMND_XFERINFO
| CMND_SBT
);
1360 msg
= msgqueue_getmsg(&host
->scsi
.msgs
, 0);
1362 acornscsi_sbic_wait(host
, ASR_DBR
, ASR_DBR
, 1000, "sending message 2");
1364 sbic_arm_write(host
, SBIC_DATA
, msg
->msg
[0]);
1366 host
->scsi
.last_message
= msg
->msg
[0];
1367 #if (DEBUG & DEBUG_MESSAGES)
1368 spi_print_msg(msg
->msg
);
1374 * ANSI standard says: (SCSI-2 Rev 10c Sect 5.6.14)
1375 * 'When a target sends this (MESSAGE_REJECT) message, it
1376 * shall change to MESSAGE IN phase and send this message
1377 * prior to requesting additional message bytes from the
1378 * initiator. This provides an interlock so that the
1379 * initiator can determine which message byte is rejected.
1381 sbic_arm_write(host
, SBIC_TRANSCNTH
, 0);
1382 sbic_arm_writenext(host
, 0);
1383 sbic_arm_writenext(host
, message_length
);
1384 acornscsi_sbic_issuecmd(host
, CMND_XFERINFO
);
1387 while ((msg
= msgqueue_getmsg(&host
->scsi
.msgs
, msgnr
++)) != NULL
) {
1389 #if (DEBUG & DEBUG_MESSAGES)
1393 if (acornscsi_write_pio(host
, msg
->msg
, &i
, msg
->length
, 1000000))
1394 printk("scsi%d: timeout while sending message\n", host
->host
->host_no
);
1396 host
->scsi
.last_message
= msg
->msg
[0];
1397 if (msg
->msg
[0] == EXTENDED_MESSAGE
)
1398 host
->scsi
.last_message
|= msg
->msg
[2] << 8;
1400 if (i
!= msg
->length
)
1405 #if (DEBUG & DEBUG_MESSAGES)
1411 * Function: void acornscsi_readstatusbyte(AS_Host *host)
1412 * Purpose : Read status byte from connected target
1413 * Params : host - host connected to target
1416 void acornscsi_readstatusbyte(AS_Host
*host
)
1418 acornscsi_sbic_issuecmd(host
, CMND_XFERINFO
|CMND_SBT
);
1419 acornscsi_sbic_wait(host
, ASR_DBR
, ASR_DBR
, 1000, "reading status byte");
1420 host
->scsi
.SCp
.Status
= sbic_arm_read(host
, SBIC_DATA
);
1424 * Function: unsigned char acornscsi_readmessagebyte(AS_Host *host)
1425 * Purpose : Read one message byte from connected target
1426 * Params : host - host connected to target
1429 unsigned char acornscsi_readmessagebyte(AS_Host
*host
)
1431 unsigned char message
;
1433 acornscsi_sbic_issuecmd(host
, CMND_XFERINFO
| CMND_SBT
);
1435 acornscsi_sbic_wait(host
, ASR_DBR
, ASR_DBR
, 1000, "for message byte");
1437 message
= sbic_arm_read(host
, SBIC_DATA
);
1439 /* wait for MSGIN-XFER-PAUSED */
1440 acornscsi_sbic_wait(host
, ASR_INT
, ASR_INT
, 1000, "for interrupt after message byte");
1442 sbic_arm_read(host
, SBIC_SSR
);
1448 * Function: void acornscsi_message(AS_Host *host)
1449 * Purpose : Read complete message from connected target & action message
1450 * Params : host - host connected to target
1453 void acornscsi_message(AS_Host
*host
)
1455 unsigned char message
[16];
1456 unsigned int msgidx
= 0, msglen
= 1;
1459 message
[msgidx
] = acornscsi_readmessagebyte(host
);
1463 if (message
[0] == EXTENDED_MESSAGE
||
1464 (message
[0] >= 0x20 && message
[0] <= 0x2f))
1469 if (message
[0] == EXTENDED_MESSAGE
)
1470 msglen
+= message
[msgidx
];
1474 if (msgidx
< msglen
) {
1475 acornscsi_sbic_issuecmd(host
, CMND_NEGATEACK
);
1477 /* wait for next msg-in */
1478 acornscsi_sbic_wait(host
, ASR_INT
, ASR_INT
, 1000, "for interrupt after negate ack");
1479 sbic_arm_read(host
, SBIC_SSR
);
1481 } while (msgidx
< msglen
);
1483 #if (DEBUG & DEBUG_MESSAGES)
1484 printk("scsi%d.%c: message in: ",
1485 host
->host
->host_no
, acornscsi_target(host
));
1486 spi_print_msg(message
);
1490 if (host
->scsi
.phase
== PHASE_RECONNECTED
) {
1492 * ANSI standard says: (Section SCSI-2 Rev. 10c Sect 5.6.17)
1493 * 'Whenever a target reconnects to an initiator to continue
1494 * a tagged I/O process, the SIMPLE QUEUE TAG message shall
1495 * be sent immediately following the IDENTIFY message...'
1497 if (message
[0] == SIMPLE_QUEUE_TAG
)
1498 host
->scsi
.reconnected
.tag
= message
[1];
1499 if (acornscsi_reconnect_finish(host
))
1500 host
->scsi
.phase
= PHASE_MSGIN
;
1503 switch (message
[0]) {
1506 case COMMAND_COMPLETE
:
1507 if (host
->scsi
.phase
!= PHASE_STATUSIN
) {
1508 printk(KERN_ERR
"scsi%d.%c: command complete following non-status in phase?\n",
1509 host
->host
->host_no
, acornscsi_target(host
));
1510 acornscsi_dumplog(host
, host
->SCpnt
->device
->id
);
1512 host
->scsi
.phase
= PHASE_DONE
;
1513 host
->scsi
.SCp
.Message
= message
[0];
1518 * ANSI standard says: (Section SCSI-2 Rev. 10c Sect 5.6.20)
1519 * 'The SAVE DATA POINTER message is sent from a target to
1520 * direct the initiator to copy the active data pointer to
1521 * the saved data pointer for the current I/O process.
1523 acornscsi_dma_cleanup(host
);
1524 host
->SCpnt
->SCp
= host
->scsi
.SCp
;
1525 host
->SCpnt
->SCp
.sent_command
= 0;
1526 host
->scsi
.phase
= PHASE_MSGIN
;
1529 case RESTORE_POINTERS
:
1531 * ANSI standard says: (Section SCSI-2 Rev. 10c Sect 5.6.19)
1532 * 'The RESTORE POINTERS message is sent from a target to
1533 * direct the initiator to copy the most recently saved
1534 * command, data, and status pointers for the I/O process
1535 * to the corresponding active pointers. The command and
1536 * status pointers shall be restored to the beginning of
1537 * the present command and status areas.'
1539 acornscsi_dma_cleanup(host
);
1540 host
->scsi
.SCp
= host
->SCpnt
->SCp
;
1541 host
->scsi
.phase
= PHASE_MSGIN
;
1546 * ANSI standard says: (Section SCSI-2 Rev. 10c Sect 6.4.2)
1547 * 'On those occasions when an error or exception condition occurs
1548 * and the target elects to repeat the information transfer, the
1549 * target may repeat the transfer either issuing a RESTORE POINTERS
1550 * message or by disconnecting without issuing a SAVE POINTERS
1551 * message. When reconnection is completed, the most recent
1552 * saved pointer values are restored.'
1554 acornscsi_dma_cleanup(host
);
1555 host
->scsi
.phase
= PHASE_DISCONNECT
;
1558 case MESSAGE_REJECT
:
1559 #if 0 /* this isn't needed any more */
1561 * If we were negociating sync transfer, we don't yet know if
1562 * this REJECT is for the sync transfer or for the tagged queue/wide
1563 * transfer. Re-initiate sync transfer negotiation now, and if
1564 * we got a REJECT in response to SDTR, then it'll be set to DONE.
1566 if (host
->device
[host
->SCpnt
->device
->id
].sync_state
== SYNC_SENT_REQUEST
)
1567 host
->device
[host
->SCpnt
->device
->id
].sync_state
= SYNC_NEGOCIATE
;
1571 * If we have any messages waiting to go out, then assert ATN now
1573 if (msgqueue_msglength(&host
->scsi
.msgs
))
1574 acornscsi_sbic_issuecmd(host
, CMND_ASSERTATN
);
1576 switch (host
->scsi
.last_message
) {
1577 #ifdef CONFIG_SCSI_ACORNSCSI_TAGGED_QUEUE
1578 case HEAD_OF_QUEUE_TAG
:
1579 case ORDERED_QUEUE_TAG
:
1580 case SIMPLE_QUEUE_TAG
:
1582 * ANSI standard says: (Section SCSI-2 Rev. 10c Sect 5.6.17)
1583 * If a target does not implement tagged queuing and a queue tag
1584 * message is received, it shall respond with a MESSAGE REJECT
1585 * message and accept the I/O process as if it were untagged.
1587 printk(KERN_NOTICE
"scsi%d.%c: disabling tagged queueing\n",
1588 host
->host
->host_no
, acornscsi_target(host
));
1589 host
->SCpnt
->device
->simple_tags
= 0;
1590 set_bit(host
->SCpnt
->device
->id
* 8 + host
->SCpnt
->device
->lun
, host
->busyluns
);
1593 case EXTENDED_MESSAGE
| (EXTENDED_SDTR
<< 8):
1595 * Target can't handle synchronous transfers
1597 printk(KERN_NOTICE
"scsi%d.%c: Using asynchronous transfer\n",
1598 host
->host
->host_no
, acornscsi_target(host
));
1599 host
->device
[host
->SCpnt
->device
->id
].sync_xfer
= SYNCHTRANSFER_2DBA
;
1600 host
->device
[host
->SCpnt
->device
->id
].sync_state
= SYNC_ASYNCHRONOUS
;
1601 sbic_arm_write(host
, SBIC_SYNCHTRANSFER
, host
->device
[host
->SCpnt
->device
->id
].sync_xfer
);
1610 /* TODO: target queue is full */
1613 case SIMPLE_QUEUE_TAG
:
1614 /* tag queue reconnect... message[1] = queue tag. Print something to indicate something happened! */
1615 printk("scsi%d.%c: reconnect queue tag %02X\n",
1616 host
->host
->host_no
, acornscsi_target(host
),
1620 case EXTENDED_MESSAGE
:
1621 switch (message
[2]) {
1622 #ifdef CONFIG_SCSI_ACORNSCSI_SYNC
1624 if (host
->device
[host
->SCpnt
->device
->id
].sync_state
== SYNC_SENT_REQUEST
) {
1626 * We requested synchronous transfers. This isn't quite right...
1627 * We can only say if this succeeded if we proceed on to execute the
1628 * command from this message. If we get a MESSAGE PARITY ERROR,
1629 * and the target retries fail, then we fallback to asynchronous mode
1631 host
->device
[host
->SCpnt
->device
->id
].sync_state
= SYNC_COMPLETED
;
1632 printk(KERN_NOTICE
"scsi%d.%c: Using synchronous transfer, offset %d, %d ns\n",
1633 host
->host
->host_no
, acornscsi_target(host
),
1634 message
[4], message
[3] * 4);
1635 host
->device
[host
->SCpnt
->device
->id
].sync_xfer
=
1636 calc_sync_xfer(message
[3] * 4, message
[4]);
1638 unsigned char period
, length
;
1640 * Target requested synchronous transfers. The agreement is only
1641 * to be in operation AFTER the target leaves message out phase.
1643 acornscsi_sbic_issuecmd(host
, CMND_ASSERTATN
);
1644 period
= max_t(unsigned int, message
[3], sdtr_period
/ 4);
1645 length
= min_t(unsigned int, message
[4], sdtr_size
);
1646 msgqueue_addmsg(&host
->scsi
.msgs
, 5, EXTENDED_MESSAGE
, 3,
1647 EXTENDED_SDTR
, period
, length
);
1648 host
->device
[host
->SCpnt
->device
->id
].sync_xfer
=
1649 calc_sync_xfer(period
* 4, length
);
1651 sbic_arm_write(host
, SBIC_SYNCHTRANSFER
, host
->device
[host
->SCpnt
->device
->id
].sync_xfer
);
1654 /* We do not accept synchronous transfers. Respond with a
1660 /* The WD33C93A is only 8-bit. We respond with a MESSAGE_REJECT
1661 * to a wide data transfer request.
1664 acornscsi_sbic_issuecmd(host
, CMND_ASSERTATN
);
1665 msgqueue_flush(&host
->scsi
.msgs
);
1666 msgqueue_addmsg(&host
->scsi
.msgs
, 1, MESSAGE_REJECT
);
1671 #ifdef CONFIG_SCSI_ACORNSCSI_LINK
1672 case LINKED_CMD_COMPLETE
:
1673 case LINKED_FLG_CMD_COMPLETE
:
1675 * We don't support linked commands yet
1678 #if (DEBUG & DEBUG_LINK)
1679 printk("scsi%d.%c: lun %d tag %d linked command complete\n",
1680 host
->host
->host_no
, acornscsi_target(host
), host
->SCpnt
->tag
);
1683 * A linked command should only terminate with one of these messages
1684 * if there are more linked commands available.
1686 if (!host
->SCpnt
->next_link
) {
1687 printk(KERN_WARNING
"scsi%d.%c: lun %d tag %d linked command complete, but no next_link\n",
1688 instance
->host_no
, acornscsi_target(host
), host
->SCpnt
->tag
);
1689 acornscsi_sbic_issuecmd(host
, CMND_ASSERTATN
);
1690 msgqueue_addmsg(&host
->scsi
.msgs
, 1, ABORT
);
1692 struct scsi_cmnd
*SCpnt
= host
->SCpnt
;
1694 acornscsi_dma_cleanup(host
);
1696 host
->SCpnt
= host
->SCpnt
->next_link
;
1697 host
->SCpnt
->tag
= SCpnt
->tag
;
1698 SCpnt
->result
= DID_OK
| host
->scsi
.SCp
.Message
<< 8 | host
->Scsi
.SCp
.Status
;
1701 /* initialise host->SCpnt->SCp */
1707 default: /* reject message */
1708 printk(KERN_ERR
"scsi%d.%c: unrecognised message %02X, rejecting\n",
1709 host
->host
->host_no
, acornscsi_target(host
),
1711 acornscsi_sbic_issuecmd(host
, CMND_ASSERTATN
);
1712 msgqueue_flush(&host
->scsi
.msgs
);
1713 msgqueue_addmsg(&host
->scsi
.msgs
, 1, MESSAGE_REJECT
);
1714 host
->scsi
.phase
= PHASE_MSGIN
;
1717 acornscsi_sbic_issuecmd(host
, CMND_NEGATEACK
);
1721 * Function: int acornscsi_buildmessages(AS_Host *host)
1722 * Purpose : build the connection messages for a host
1723 * Params : host - host to add messages to
1726 void acornscsi_buildmessages(AS_Host
*host
)
1729 /* does the device need resetting? */
1731 msgqueue_addmsg(&host
->scsi
.msgs
, 1, BUS_DEVICE_RESET
);
1736 msgqueue_addmsg(&host
->scsi
.msgs
, 1,
1737 IDENTIFY(host
->device
[host
->SCpnt
->device
->id
].disconnect_ok
,
1738 host
->SCpnt
->device
->lun
));
1741 /* does the device need the current command aborted */
1743 acornscsi_abortcmd(host
->SCpnt
->tag
);
1748 #ifdef CONFIG_SCSI_ACORNSCSI_TAGGED_QUEUE
1749 if (host
->SCpnt
->tag
) {
1750 unsigned int tag_type
;
1752 if (host
->SCpnt
->cmnd
[0] == REQUEST_SENSE
||
1753 host
->SCpnt
->cmnd
[0] == TEST_UNIT_READY
||
1754 host
->SCpnt
->cmnd
[0] == INQUIRY
)
1755 tag_type
= HEAD_OF_QUEUE_TAG
;
1757 tag_type
= SIMPLE_QUEUE_TAG
;
1758 msgqueue_addmsg(&host
->scsi
.msgs
, 2, tag_type
, host
->SCpnt
->tag
);
1762 #ifdef CONFIG_SCSI_ACORNSCSI_SYNC
1763 if (host
->device
[host
->SCpnt
->device
->id
].sync_state
== SYNC_NEGOCIATE
) {
1764 host
->device
[host
->SCpnt
->device
->id
].sync_state
= SYNC_SENT_REQUEST
;
1765 msgqueue_addmsg(&host
->scsi
.msgs
, 5,
1766 EXTENDED_MESSAGE
, 3, EXTENDED_SDTR
,
1767 sdtr_period
/ 4, sdtr_size
);
1773 * Function: int acornscsi_starttransfer(AS_Host *host)
1774 * Purpose : transfer data to/from connected target
1775 * Params : host - host to which target is connected
1776 * Returns : 0 if failure
1779 int acornscsi_starttransfer(AS_Host
*host
)
1783 if (!host
->scsi
.SCp
.ptr
/*&& host->scsi.SCp.this_residual*/) {
1784 printk(KERN_ERR
"scsi%d.%c: null buffer passed to acornscsi_starttransfer\n",
1785 host
->host
->host_no
, acornscsi_target(host
));
1789 residual
= scsi_bufflen(host
->SCpnt
) - host
->scsi
.SCp
.scsi_xferred
;
1791 sbic_arm_write(host
, SBIC_SYNCHTRANSFER
, host
->device
[host
->SCpnt
->device
->id
].sync_xfer
);
1792 sbic_arm_writenext(host
, residual
>> 16);
1793 sbic_arm_writenext(host
, residual
>> 8);
1794 sbic_arm_writenext(host
, residual
);
1795 acornscsi_sbic_issuecmd(host
, CMND_XFERINFO
);
1799 /* =========================================================================================
1800 * Connection & Disconnection
1803 * Function : acornscsi_reconnect(AS_Host *host)
1804 * Purpose : reconnect a previously disconnected command
1805 * Params : host - host specific data
1806 * Remarks : SCSI spec says:
1807 * 'The set of active pointers is restored from the set
1808 * of saved pointers upon reconnection of the I/O process'
1811 int acornscsi_reconnect(AS_Host
*host
)
1813 unsigned int target
, lun
, ok
= 0;
1815 target
= sbic_arm_read(host
, SBIC_SOURCEID
);
1818 printk(KERN_ERR
"scsi%d: invalid source id after reselection "
1819 "- device fault?\n",
1820 host
->host
->host_no
);
1824 if (host
->SCpnt
&& !host
->scsi
.disconnectable
) {
1825 printk(KERN_ERR
"scsi%d.%d: reconnected while command in "
1826 "progress to target %d?\n",
1827 host
->host
->host_no
, target
, host
->SCpnt
->device
->id
);
1831 lun
= sbic_arm_read(host
, SBIC_DATA
) & 7;
1833 host
->scsi
.reconnected
.target
= target
;
1834 host
->scsi
.reconnected
.lun
= lun
;
1835 host
->scsi
.reconnected
.tag
= 0;
1837 if (host
->scsi
.disconnectable
&& host
->SCpnt
&&
1838 host
->SCpnt
->device
->id
== target
&& host
->SCpnt
->device
->lun
== lun
)
1841 if (!ok
&& queue_probetgtlun(&host
->queues
.disconnected
, target
, lun
))
1844 ADD_STATUS(target
, 0x81, host
->scsi
.phase
, 0);
1847 host
->scsi
.phase
= PHASE_RECONNECTED
;
1849 /* this doesn't seem to work */
1850 printk(KERN_ERR
"scsi%d.%c: reselected with no command "
1851 "to reconnect with\n",
1852 host
->host
->host_no
, '0' + target
);
1853 acornscsi_dumplog(host
, target
);
1854 acornscsi_abortcmd(host
, 0);
1856 queue_add_cmd_tail(&host
->queues
.disconnected
, host
->SCpnt
);
1860 acornscsi_sbic_issuecmd(host
, CMND_NEGATEACK
);
1865 * Function: int acornscsi_reconect_finish(AS_Host *host)
1866 * Purpose : finish reconnecting a command
1867 * Params : host - host to complete
1868 * Returns : 0 if failed
1871 int acornscsi_reconnect_finish(AS_Host
*host
)
1873 if (host
->scsi
.disconnectable
&& host
->SCpnt
) {
1874 host
->scsi
.disconnectable
= 0;
1875 if (host
->SCpnt
->device
->id
== host
->scsi
.reconnected
.target
&&
1876 host
->SCpnt
->device
->lun
== host
->scsi
.reconnected
.lun
&&
1877 host
->SCpnt
->tag
== host
->scsi
.reconnected
.tag
) {
1878 #if (DEBUG & (DEBUG_QUEUES|DEBUG_DISCON))
1879 DBG(host
->SCpnt
, printk("scsi%d.%c: reconnected",
1880 host
->host
->host_no
, acornscsi_target(host
)));
1883 queue_add_cmd_tail(&host
->queues
.disconnected
, host
->SCpnt
);
1884 #if (DEBUG & (DEBUG_QUEUES|DEBUG_DISCON))
1885 DBG(host
->SCpnt
, printk("scsi%d.%c: had to move command "
1886 "to disconnected queue\n",
1887 host
->host
->host_no
, acornscsi_target(host
)));
1893 host
->SCpnt
= queue_remove_tgtluntag(&host
->queues
.disconnected
,
1894 host
->scsi
.reconnected
.target
,
1895 host
->scsi
.reconnected
.lun
,
1896 host
->scsi
.reconnected
.tag
);
1897 #if (DEBUG & (DEBUG_QUEUES|DEBUG_DISCON))
1898 DBG(host
->SCpnt
, printk("scsi%d.%c: had to get command",
1899 host
->host
->host_no
, acornscsi_target(host
)));
1904 acornscsi_abortcmd(host
, host
->scsi
.reconnected
.tag
);
1907 * Restore data pointer from SAVED pointers.
1909 host
->scsi
.SCp
= host
->SCpnt
->SCp
;
1910 #if (DEBUG & (DEBUG_QUEUES|DEBUG_DISCON))
1911 printk(", data pointers: [%p, %X]",
1912 host
->scsi
.SCp
.ptr
, host
->scsi
.SCp
.this_residual
);
1915 #if (DEBUG & (DEBUG_QUEUES|DEBUG_DISCON))
1919 host
->dma
.transferred
= host
->scsi
.SCp
.scsi_xferred
;
1921 return host
->SCpnt
!= NULL
;
1925 * Function: void acornscsi_disconnect_unexpected(AS_Host *host)
1926 * Purpose : handle an unexpected disconnect
1927 * Params : host - host on which disconnect occurred
1930 void acornscsi_disconnect_unexpected(AS_Host
*host
)
1932 printk(KERN_ERR
"scsi%d.%c: unexpected disconnect\n",
1933 host
->host
->host_no
, acornscsi_target(host
));
1934 #if (DEBUG & DEBUG_ABORT)
1935 acornscsi_dumplog(host
, 8);
1938 acornscsi_done(host
, &host
->SCpnt
, DID_ERROR
);
1942 * Function: void acornscsi_abortcmd(AS_host *host, unsigned char tag)
1943 * Purpose : abort a currently executing command
1944 * Params : host - host with connected command to abort
1945 * tag - tag to abort
1948 void acornscsi_abortcmd(AS_Host
*host
, unsigned char tag
)
1950 host
->scsi
.phase
= PHASE_ABORTED
;
1951 sbic_arm_write(host
, SBIC_CMND
, CMND_ASSERTATN
);
1953 msgqueue_flush(&host
->scsi
.msgs
);
1954 #ifdef CONFIG_SCSI_ACORNSCSI_TAGGED_QUEUE
1956 msgqueue_addmsg(&host
->scsi
.msgs
, 2, ABORT_TAG
, tag
);
1959 msgqueue_addmsg(&host
->scsi
.msgs
, 1, ABORT
);
1962 /* ==========================================================================================
1963 * Interrupt routines.
1966 * Function: int acornscsi_sbicintr(AS_Host *host)
1967 * Purpose : handle interrupts from SCSI device
1968 * Params : host - host to process
1969 * Returns : INTR_PROCESS if expecting another SBIC interrupt
1970 * INTR_IDLE if no interrupt
1971 * INTR_NEXT_COMMAND if we have finished processing the command
1974 intr_ret_t
acornscsi_sbicintr(AS_Host
*host
, int in_irq
)
1976 unsigned int asr
, ssr
;
1978 asr
= sbic_arm_read(host
, SBIC_ASR
);
1979 if (!(asr
& ASR_INT
))
1982 ssr
= sbic_arm_read(host
, SBIC_SSR
);
1984 #if (DEBUG & DEBUG_PHASES)
1985 print_sbic_status(asr
, ssr
, host
->scsi
.phase
);
1988 ADD_STATUS(8, ssr
, host
->scsi
.phase
, in_irq
);
1990 if (host
->SCpnt
&& !host
->scsi
.disconnectable
)
1991 ADD_STATUS(host
->SCpnt
->device
->id
, ssr
, host
->scsi
.phase
, in_irq
);
1994 case 0x00: /* reset state - not advanced */
1995 printk(KERN_ERR
"scsi%d: reset in standard mode but wanted advanced mode.\n",
1996 host
->host
->host_no
);
1997 /* setup sbic - WD33C93A */
1998 sbic_arm_write(host
, SBIC_OWNID
, OWNID_EAF
| host
->host
->this_id
);
1999 sbic_arm_write(host
, SBIC_CMND
, CMND_RESET
);
2002 case 0x01: /* reset state - advanced */
2003 sbic_arm_write(host
, SBIC_CTRL
, INIT_SBICDMA
| CTRL_IDI
);
2004 sbic_arm_write(host
, SBIC_TIMEOUT
, TIMEOUT_TIME
);
2005 sbic_arm_write(host
, SBIC_SYNCHTRANSFER
, SYNCHTRANSFER_2DBA
);
2006 sbic_arm_write(host
, SBIC_SOURCEID
, SOURCEID_ER
| SOURCEID_DSP
);
2007 msgqueue_flush(&host
->scsi
.msgs
);
2010 case 0x41: /* unexpected disconnect aborted command */
2011 acornscsi_disconnect_unexpected(host
);
2012 return INTR_NEXT_COMMAND
;
2015 switch (host
->scsi
.phase
) {
2016 case PHASE_CONNECTING
: /* STATE: command removed from issue queue */
2018 case 0x11: /* -> PHASE_CONNECTED */
2019 /* BUS FREE -> SELECTION */
2020 host
->scsi
.phase
= PHASE_CONNECTED
;
2021 msgqueue_flush(&host
->scsi
.msgs
);
2022 host
->dma
.transferred
= host
->scsi
.SCp
.scsi_xferred
;
2023 /* 33C93 gives next interrupt indicating bus phase */
2024 asr
= sbic_arm_read(host
, SBIC_ASR
);
2025 if (!(asr
& ASR_INT
))
2027 ssr
= sbic_arm_read(host
, SBIC_SSR
);
2028 ADD_STATUS(8, ssr
, host
->scsi
.phase
, 1);
2029 ADD_STATUS(host
->SCpnt
->device
->id
, ssr
, host
->scsi
.phase
, 1);
2032 case 0x42: /* select timed out */
2034 acornscsi_done(host
, &host
->SCpnt
, DID_NO_CONNECT
);
2035 return INTR_NEXT_COMMAND
;
2037 case 0x81: /* -> PHASE_RECONNECTED or PHASE_ABORTED */
2038 /* BUS FREE -> RESELECTION */
2039 host
->origSCpnt
= host
->SCpnt
;
2041 msgqueue_flush(&host
->scsi
.msgs
);
2042 acornscsi_reconnect(host
);
2046 printk(KERN_ERR
"scsi%d.%c: PHASE_CONNECTING, SSR %02X?\n",
2047 host
->host
->host_no
, acornscsi_target(host
), ssr
);
2048 acornscsi_dumplog(host
, host
->SCpnt
? host
->SCpnt
->device
->id
: 8);
2049 acornscsi_abortcmd(host
, host
->SCpnt
->tag
);
2051 return INTR_PROCESSING
;
2054 case PHASE_CONNECTED
: /* STATE: device selected ok */
2057 case 0x8a: /* -> PHASE_COMMAND, PHASE_COMMANDPAUSED */
2058 /* SELECTION -> COMMAND */
2059 acornscsi_sendcommand(host
);
2062 case 0x8b: /* -> PHASE_STATUS */
2063 /* SELECTION -> STATUS */
2064 acornscsi_readstatusbyte(host
);
2065 host
->scsi
.phase
= PHASE_STATUSIN
;
2069 case 0x8e: /* -> PHASE_MSGOUT */
2070 /* SELECTION ->MESSAGE OUT */
2071 host
->scsi
.phase
= PHASE_MSGOUT
;
2072 acornscsi_buildmessages(host
);
2073 acornscsi_sendmessage(host
);
2076 /* these should not happen */
2077 case 0x85: /* target disconnected */
2078 acornscsi_done(host
, &host
->SCpnt
, DID_ERROR
);
2082 printk(KERN_ERR
"scsi%d.%c: PHASE_CONNECTED, SSR %02X?\n",
2083 host
->host
->host_no
, acornscsi_target(host
), ssr
);
2084 acornscsi_dumplog(host
, host
->SCpnt
? host
->SCpnt
->device
->id
: 8);
2085 acornscsi_abortcmd(host
, host
->SCpnt
->tag
);
2087 return INTR_PROCESSING
;
2089 case PHASE_MSGOUT
: /* STATE: connected & sent IDENTIFY message */
2091 * SCSI standard says that MESSAGE OUT phases can be followed by a
2092 * DATA phase, STATUS phase, MESSAGE IN phase or COMMAND phase
2095 case 0x8a: /* -> PHASE_COMMAND, PHASE_COMMANDPAUSED */
2096 case 0x1a: /* -> PHASE_COMMAND, PHASE_COMMANDPAUSED */
2097 /* MESSAGE OUT -> COMMAND */
2098 acornscsi_sendcommand(host
);
2101 case 0x8b: /* -> PHASE_STATUS */
2102 case 0x1b: /* -> PHASE_STATUS */
2103 /* MESSAGE OUT -> STATUS */
2104 acornscsi_readstatusbyte(host
);
2105 host
->scsi
.phase
= PHASE_STATUSIN
;
2108 case 0x8e: /* -> PHASE_MSGOUT */
2109 /* MESSAGE_OUT(MESSAGE_IN) ->MESSAGE OUT */
2110 acornscsi_sendmessage(host
);
2113 case 0x4f: /* -> PHASE_MSGIN, PHASE_DISCONNECT */
2114 case 0x1f: /* -> PHASE_MSGIN, PHASE_DISCONNECT */
2115 /* MESSAGE OUT -> MESSAGE IN */
2116 acornscsi_message(host
);
2120 printk(KERN_ERR
"scsi%d.%c: PHASE_MSGOUT, SSR %02X?\n",
2121 host
->host
->host_no
, acornscsi_target(host
), ssr
);
2122 acornscsi_dumplog(host
, host
->SCpnt
? host
->SCpnt
->device
->id
: 8);
2124 return INTR_PROCESSING
;
2126 case PHASE_COMMAND
: /* STATE: connected & command sent */
2128 case 0x18: /* -> PHASE_DATAOUT */
2129 /* COMMAND -> DATA OUT */
2130 if (host
->scsi
.SCp
.sent_command
!= host
->SCpnt
->cmd_len
)
2131 acornscsi_abortcmd(host
, host
->SCpnt
->tag
);
2132 acornscsi_dma_setup(host
, DMA_OUT
);
2133 if (!acornscsi_starttransfer(host
))
2134 acornscsi_abortcmd(host
, host
->SCpnt
->tag
);
2135 host
->scsi
.phase
= PHASE_DATAOUT
;
2138 case 0x19: /* -> PHASE_DATAIN */
2139 /* COMMAND -> DATA IN */
2140 if (host
->scsi
.SCp
.sent_command
!= host
->SCpnt
->cmd_len
)
2141 acornscsi_abortcmd(host
, host
->SCpnt
->tag
);
2142 acornscsi_dma_setup(host
, DMA_IN
);
2143 if (!acornscsi_starttransfer(host
))
2144 acornscsi_abortcmd(host
, host
->SCpnt
->tag
);
2145 host
->scsi
.phase
= PHASE_DATAIN
;
2148 case 0x1b: /* -> PHASE_STATUS */
2149 /* COMMAND -> STATUS */
2150 acornscsi_readstatusbyte(host
);
2151 host
->scsi
.phase
= PHASE_STATUSIN
;
2154 case 0x1e: /* -> PHASE_MSGOUT */
2155 /* COMMAND -> MESSAGE OUT */
2156 acornscsi_sendmessage(host
);
2159 case 0x1f: /* -> PHASE_MSGIN, PHASE_DISCONNECT */
2160 /* COMMAND -> MESSAGE IN */
2161 acornscsi_message(host
);
2165 printk(KERN_ERR
"scsi%d.%c: PHASE_COMMAND, SSR %02X?\n",
2166 host
->host
->host_no
, acornscsi_target(host
), ssr
);
2167 acornscsi_dumplog(host
, host
->SCpnt
? host
->SCpnt
->device
->id
: 8);
2169 return INTR_PROCESSING
;
2171 case PHASE_DISCONNECT
: /* STATE: connected, received DISCONNECT msg */
2172 if (ssr
== 0x85) { /* -> PHASE_IDLE */
2173 host
->scsi
.disconnectable
= 1;
2174 host
->scsi
.reconnected
.tag
= 0;
2175 host
->scsi
.phase
= PHASE_IDLE
;
2176 host
->stats
.disconnects
+= 1;
2178 printk(KERN_ERR
"scsi%d.%c: PHASE_DISCONNECT, SSR %02X instead of disconnect?\n",
2179 host
->host
->host_no
, acornscsi_target(host
), ssr
);
2180 acornscsi_dumplog(host
, host
->SCpnt
? host
->SCpnt
->device
->id
: 8);
2182 return INTR_NEXT_COMMAND
;
2184 case PHASE_IDLE
: /* STATE: disconnected */
2185 if (ssr
== 0x81) /* -> PHASE_RECONNECTED or PHASE_ABORTED */
2186 acornscsi_reconnect(host
);
2188 printk(KERN_ERR
"scsi%d.%c: PHASE_IDLE, SSR %02X while idle?\n",
2189 host
->host
->host_no
, acornscsi_target(host
), ssr
);
2190 acornscsi_dumplog(host
, host
->SCpnt
? host
->SCpnt
->device
->id
: 8);
2192 return INTR_PROCESSING
;
2194 case PHASE_RECONNECTED
: /* STATE: device reconnected to initiator */
2196 * Command reconnected - if MESGIN, get message - it may be
2197 * the tag. If not, get command out of disconnected queue
2200 * If we reconnected and we're not in MESSAGE IN phase after IDENTIFY,
2201 * reconnect I_T_L command
2203 if (ssr
!= 0x8f && !acornscsi_reconnect_finish(host
))
2205 ADD_STATUS(host
->SCpnt
->device
->id
, ssr
, host
->scsi
.phase
, in_irq
);
2207 case 0x88: /* data out phase */
2208 /* -> PHASE_DATAOUT */
2209 /* MESSAGE IN -> DATA OUT */
2210 acornscsi_dma_setup(host
, DMA_OUT
);
2211 if (!acornscsi_starttransfer(host
))
2212 acornscsi_abortcmd(host
, host
->SCpnt
->tag
);
2213 host
->scsi
.phase
= PHASE_DATAOUT
;
2216 case 0x89: /* data in phase */
2217 /* -> PHASE_DATAIN */
2218 /* MESSAGE IN -> DATA IN */
2219 acornscsi_dma_setup(host
, DMA_IN
);
2220 if (!acornscsi_starttransfer(host
))
2221 acornscsi_abortcmd(host
, host
->SCpnt
->tag
);
2222 host
->scsi
.phase
= PHASE_DATAIN
;
2225 case 0x8a: /* command out */
2226 /* MESSAGE IN -> COMMAND */
2227 acornscsi_sendcommand(host
);/* -> PHASE_COMMAND, PHASE_COMMANDPAUSED */
2230 case 0x8b: /* status in */
2231 /* -> PHASE_STATUSIN */
2232 /* MESSAGE IN -> STATUS */
2233 acornscsi_readstatusbyte(host
);
2234 host
->scsi
.phase
= PHASE_STATUSIN
;
2237 case 0x8e: /* message out */
2238 /* -> PHASE_MSGOUT */
2239 /* MESSAGE IN -> MESSAGE OUT */
2240 acornscsi_sendmessage(host
);
2243 case 0x8f: /* message in */
2244 acornscsi_message(host
); /* -> PHASE_MSGIN, PHASE_DISCONNECT */
2248 printk(KERN_ERR
"scsi%d.%c: PHASE_RECONNECTED, SSR %02X after reconnect?\n",
2249 host
->host
->host_no
, acornscsi_target(host
), ssr
);
2250 acornscsi_dumplog(host
, host
->SCpnt
? host
->SCpnt
->device
->id
: 8);
2252 return INTR_PROCESSING
;
2254 case PHASE_DATAIN
: /* STATE: transferred data in */
2256 * This is simple - if we disconnect then the DMA address & count is
2260 case 0x19: /* -> PHASE_DATAIN */
2261 case 0x89: /* -> PHASE_DATAIN */
2262 acornscsi_abortcmd(host
, host
->SCpnt
->tag
);
2265 case 0x1b: /* -> PHASE_STATUSIN */
2266 case 0x4b: /* -> PHASE_STATUSIN */
2267 case 0x8b: /* -> PHASE_STATUSIN */
2268 /* DATA IN -> STATUS */
2269 host
->scsi
.SCp
.scsi_xferred
= scsi_bufflen(host
->SCpnt
) -
2270 acornscsi_sbic_xfcount(host
);
2271 acornscsi_dma_stop(host
);
2272 acornscsi_readstatusbyte(host
);
2273 host
->scsi
.phase
= PHASE_STATUSIN
;
2276 case 0x1e: /* -> PHASE_MSGOUT */
2277 case 0x4e: /* -> PHASE_MSGOUT */
2278 case 0x8e: /* -> PHASE_MSGOUT */
2279 /* DATA IN -> MESSAGE OUT */
2280 host
->scsi
.SCp
.scsi_xferred
= scsi_bufflen(host
->SCpnt
) -
2281 acornscsi_sbic_xfcount(host
);
2282 acornscsi_dma_stop(host
);
2283 acornscsi_sendmessage(host
);
2286 case 0x1f: /* message in */
2287 case 0x4f: /* message in */
2288 case 0x8f: /* message in */
2289 /* DATA IN -> MESSAGE IN */
2290 host
->scsi
.SCp
.scsi_xferred
= scsi_bufflen(host
->SCpnt
) -
2291 acornscsi_sbic_xfcount(host
);
2292 acornscsi_dma_stop(host
);
2293 acornscsi_message(host
); /* -> PHASE_MSGIN, PHASE_DISCONNECT */
2297 printk(KERN_ERR
"scsi%d.%c: PHASE_DATAIN, SSR %02X?\n",
2298 host
->host
->host_no
, acornscsi_target(host
), ssr
);
2299 acornscsi_dumplog(host
, host
->SCpnt
? host
->SCpnt
->device
->id
: 8);
2301 return INTR_PROCESSING
;
2303 case PHASE_DATAOUT
: /* STATE: transferred data out */
2305 * This is more complicated - if we disconnect, the DMA could be 12
2306 * bytes ahead of us. We need to correct this.
2309 case 0x18: /* -> PHASE_DATAOUT */
2310 case 0x88: /* -> PHASE_DATAOUT */
2311 acornscsi_abortcmd(host
, host
->SCpnt
->tag
);
2314 case 0x1b: /* -> PHASE_STATUSIN */
2315 case 0x4b: /* -> PHASE_STATUSIN */
2316 case 0x8b: /* -> PHASE_STATUSIN */
2317 /* DATA OUT -> STATUS */
2318 host
->scsi
.SCp
.scsi_xferred
= scsi_bufflen(host
->SCpnt
) -
2319 acornscsi_sbic_xfcount(host
);
2320 acornscsi_dma_stop(host
);
2321 acornscsi_dma_adjust(host
);
2322 acornscsi_readstatusbyte(host
);
2323 host
->scsi
.phase
= PHASE_STATUSIN
;
2326 case 0x1e: /* -> PHASE_MSGOUT */
2327 case 0x4e: /* -> PHASE_MSGOUT */
2328 case 0x8e: /* -> PHASE_MSGOUT */
2329 /* DATA OUT -> MESSAGE OUT */
2330 host
->scsi
.SCp
.scsi_xferred
= scsi_bufflen(host
->SCpnt
) -
2331 acornscsi_sbic_xfcount(host
);
2332 acornscsi_dma_stop(host
);
2333 acornscsi_dma_adjust(host
);
2334 acornscsi_sendmessage(host
);
2337 case 0x1f: /* message in */
2338 case 0x4f: /* message in */
2339 case 0x8f: /* message in */
2340 /* DATA OUT -> MESSAGE IN */
2341 host
->scsi
.SCp
.scsi_xferred
= scsi_bufflen(host
->SCpnt
) -
2342 acornscsi_sbic_xfcount(host
);
2343 acornscsi_dma_stop(host
);
2344 acornscsi_dma_adjust(host
);
2345 acornscsi_message(host
); /* -> PHASE_MSGIN, PHASE_DISCONNECT */
2349 printk(KERN_ERR
"scsi%d.%c: PHASE_DATAOUT, SSR %02X?\n",
2350 host
->host
->host_no
, acornscsi_target(host
), ssr
);
2351 acornscsi_dumplog(host
, host
->SCpnt
? host
->SCpnt
->device
->id
: 8);
2353 return INTR_PROCESSING
;
2355 case PHASE_STATUSIN
: /* STATE: status in complete */
2357 case 0x1f: /* -> PHASE_MSGIN, PHASE_DONE, PHASE_DISCONNECT */
2358 case 0x8f: /* -> PHASE_MSGIN, PHASE_DONE, PHASE_DISCONNECT */
2359 /* STATUS -> MESSAGE IN */
2360 acornscsi_message(host
);
2363 case 0x1e: /* -> PHASE_MSGOUT */
2364 case 0x8e: /* -> PHASE_MSGOUT */
2365 /* STATUS -> MESSAGE OUT */
2366 acornscsi_sendmessage(host
);
2370 printk(KERN_ERR
"scsi%d.%c: PHASE_STATUSIN, SSR %02X instead of MESSAGE_IN?\n",
2371 host
->host
->host_no
, acornscsi_target(host
), ssr
);
2372 acornscsi_dumplog(host
, host
->SCpnt
? host
->SCpnt
->device
->id
: 8);
2374 return INTR_PROCESSING
;
2376 case PHASE_MSGIN
: /* STATE: message in */
2378 case 0x1e: /* -> PHASE_MSGOUT */
2379 case 0x4e: /* -> PHASE_MSGOUT */
2380 case 0x8e: /* -> PHASE_MSGOUT */
2381 /* MESSAGE IN -> MESSAGE OUT */
2382 acornscsi_sendmessage(host
);
2385 case 0x1f: /* -> PHASE_MSGIN, PHASE_DONE, PHASE_DISCONNECT */
2389 acornscsi_message(host
);
2393 printk("scsi%d.%c: strange message in disconnection\n",
2394 host
->host
->host_no
, acornscsi_target(host
));
2395 acornscsi_dumplog(host
, host
->SCpnt
? host
->SCpnt
->device
->id
: 8);
2396 acornscsi_done(host
, &host
->SCpnt
, DID_ERROR
);
2400 printk(KERN_ERR
"scsi%d.%c: PHASE_MSGIN, SSR %02X after message in?\n",
2401 host
->host
->host_no
, acornscsi_target(host
), ssr
);
2402 acornscsi_dumplog(host
, host
->SCpnt
? host
->SCpnt
->device
->id
: 8);
2404 return INTR_PROCESSING
;
2406 case PHASE_DONE
: /* STATE: received status & message */
2408 case 0x85: /* -> PHASE_IDLE */
2409 acornscsi_done(host
, &host
->SCpnt
, DID_OK
);
2410 return INTR_NEXT_COMMAND
;
2414 acornscsi_sendmessage(host
);
2418 printk(KERN_ERR
"scsi%d.%c: PHASE_DONE, SSR %02X instead of disconnect?\n",
2419 host
->host
->host_no
, acornscsi_target(host
), ssr
);
2420 acornscsi_dumplog(host
, host
->SCpnt
? host
->SCpnt
->device
->id
: 8);
2422 return INTR_PROCESSING
;
2428 acornscsi_done(host
, &host
->SCpnt
, DID_ABORT
);
2430 clear_bit(host
->scsi
.reconnected
.target
* 8 + host
->scsi
.reconnected
.lun
,
2432 host
->scsi
.phase
= PHASE_IDLE
;
2434 return INTR_NEXT_COMMAND
;
2440 acornscsi_sendmessage(host
);
2444 printk(KERN_ERR
"scsi%d.%c: PHASE_ABORTED, SSR %02X?\n",
2445 host
->host
->host_no
, acornscsi_target(host
), ssr
);
2446 acornscsi_dumplog(host
, host
->SCpnt
? host
->SCpnt
->device
->id
: 8);
2448 return INTR_PROCESSING
;
2451 printk(KERN_ERR
"scsi%d.%c: unknown driver phase %d\n",
2452 host
->host
->host_no
, acornscsi_target(host
), ssr
);
2453 acornscsi_dumplog(host
, host
->SCpnt
? host
->SCpnt
->device
->id
: 8);
2455 return INTR_PROCESSING
;
2459 * Prototype: void acornscsi_intr(int irq, void *dev_id)
2460 * Purpose : handle interrupts from Acorn SCSI card
2461 * Params : irq - interrupt number
2462 * dev_id - device specific data (AS_Host structure)
2465 acornscsi_intr(int irq
, void *dev_id
)
2467 AS_Host
*host
= (AS_Host
*)dev_id
;
2475 iostatus
= readb(host
->fast
+ INT_REG
);
2478 acornscsi_dma_intr(host
);
2479 iostatus
= readb(host
->fast
+ INT_REG
);
2483 ret
= acornscsi_sbicintr(host
, in_irq
);
2486 * If we have a transfer pending, start it.
2487 * Only start it if the interface has already started transferring
2490 if (host
->dma
.xfer_required
)
2491 acornscsi_dma_xfer(host
);
2493 if (ret
== INTR_NEXT_COMMAND
)
2494 ret
= acornscsi_kick(host
);
2497 } while (ret
!= INTR_IDLE
);
2502 /*=============================================================================================
2503 * Interfaces between interrupt handler and rest of scsi code
2507 * Function : acornscsi_queuecmd(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *))
2508 * Purpose : queues a SCSI command
2509 * Params : cmd - SCSI command
2510 * done - function called on completion, with pointer to command descriptor
2511 * Returns : 0, or < 0 on error.
2513 static int acornscsi_queuecmd_lck(struct scsi_cmnd
*SCpnt
,
2514 void (*done
)(struct scsi_cmnd
*))
2516 AS_Host
*host
= (AS_Host
*)SCpnt
->device
->host
->hostdata
;
2519 /* there should be some way of rejecting errors like this without panicing... */
2520 panic("scsi%d: queuecommand called with NULL done function [cmd=%p]",
2521 host
->host
->host_no
, SCpnt
);
2525 #if (DEBUG & DEBUG_NO_WRITE)
2526 if (acornscsi_cmdtype(SCpnt
->cmnd
[0]) == CMD_WRITE
&& (NO_WRITE
& (1 << SCpnt
->device
->id
))) {
2527 printk(KERN_CRIT
"scsi%d.%c: WRITE attempted with NO_WRITE flag set\n",
2528 host
->host
->host_no
, '0' + SCpnt
->device
->id
);
2529 SCpnt
->result
= DID_NO_CONNECT
<< 16;
2535 SCpnt
->scsi_done
= done
;
2536 SCpnt
->host_scribble
= NULL
;
2539 SCpnt
->SCp
.phase
= (int)acornscsi_datadirection(SCpnt
->cmnd
[0]);
2540 SCpnt
->SCp
.sent_command
= 0;
2541 SCpnt
->SCp
.scsi_xferred
= 0;
2545 host
->stats
.queues
+= 1;
2548 unsigned long flags
;
2550 if (!queue_add_cmd_ordered(&host
->queues
.issue
, SCpnt
)) {
2551 SCpnt
->result
= DID_ERROR
<< 16;
2555 local_irq_save(flags
);
2556 if (host
->scsi
.phase
== PHASE_IDLE
)
2557 acornscsi_kick(host
);
2558 local_irq_restore(flags
);
2563 DEF_SCSI_QCMD(acornscsi_queuecmd
)
2566 * Prototype: void acornscsi_reportstatus(struct scsi_cmnd **SCpntp1, struct scsi_cmnd **SCpntp2, int result)
2567 * Purpose : pass a result to *SCpntp1, and check if *SCpntp1 = *SCpntp2
2568 * Params : SCpntp1 - pointer to command to return
2569 * SCpntp2 - pointer to command to check
2570 * result - result to pass back to mid-level done function
2571 * Returns : *SCpntp2 = NULL if *SCpntp1 is the same command structure as *SCpntp2.
2573 static inline void acornscsi_reportstatus(struct scsi_cmnd
**SCpntp1
,
2574 struct scsi_cmnd
**SCpntp2
,
2577 struct scsi_cmnd
*SCpnt
= *SCpntp1
;
2582 SCpnt
->result
= result
;
2583 SCpnt
->scsi_done(SCpnt
);
2586 if (SCpnt
== *SCpntp2
)
2590 enum res_abort
{ res_not_running
, res_success
, res_success_clear
, res_snooze
};
2593 * Prototype: enum res acornscsi_do_abort(struct scsi_cmnd *SCpnt)
2594 * Purpose : abort a command on this host
2595 * Params : SCpnt - command to abort
2596 * Returns : our abort status
2598 static enum res_abort
acornscsi_do_abort(AS_Host
*host
, struct scsi_cmnd
*SCpnt
)
2600 enum res_abort res
= res_not_running
;
2602 if (queue_remove_cmd(&host
->queues
.issue
, SCpnt
)) {
2604 * The command was on the issue queue, and has not been
2605 * issued yet. We can remove the command from the queue,
2606 * and acknowledge the abort. Neither the devices nor the
2607 * interface know about the command.
2609 //#if (DEBUG & DEBUG_ABORT)
2610 printk("on issue queue ");
2613 } else if (queue_remove_cmd(&host
->queues
.disconnected
, SCpnt
)) {
2615 * The command was on the disconnected queue. Simply
2616 * acknowledge the abort condition, and when the target
2617 * reconnects, we will give it an ABORT message. The
2618 * target should then disconnect, and we will clear
2621 //#if (DEBUG & DEBUG_ABORT)
2622 printk("on disconnected queue ");
2625 } else if (host
->SCpnt
== SCpnt
) {
2626 unsigned long flags
;
2628 //#if (DEBUG & DEBUG_ABORT)
2629 printk("executing ");
2632 local_irq_save(flags
);
2633 switch (host
->scsi
.phase
) {
2635 * If the interface is idle, and the command is 'disconnectable',
2636 * then it is the same as on the disconnected queue. We simply
2637 * remove all traces of the command. When the target reconnects,
2638 * we will give it an ABORT message since the command could not
2639 * be found. When the target finally disconnects, we will clear
2643 if (host
->scsi
.disconnectable
) {
2644 host
->scsi
.disconnectable
= 0;
2651 * If the command has connected and done nothing further,
2652 * simply force a disconnect. We also need to clear the
2655 case PHASE_CONNECTED
:
2656 sbic_arm_write(host
, SBIC_CMND
, CMND_DISCONNECT
);
2658 res
= res_success_clear
;
2662 acornscsi_abortcmd(host
, host
->SCpnt
->tag
);
2665 local_irq_restore(flags
);
2666 } else if (host
->origSCpnt
== SCpnt
) {
2668 * The command will be executed next, but a command
2669 * is currently using the interface. This is similar to
2670 * being on the issue queue, except the busylun bit has
2673 host
->origSCpnt
= NULL
;
2674 //#if (DEBUG & DEBUG_ABORT)
2675 printk("waiting for execution ");
2677 res
= res_success_clear
;
2685 * Prototype: int acornscsi_abort(struct scsi_cmnd *SCpnt)
2686 * Purpose : abort a command on this host
2687 * Params : SCpnt - command to abort
2688 * Returns : one of SCSI_ABORT_ macros
2690 int acornscsi_abort(struct scsi_cmnd
*SCpnt
)
2692 AS_Host
*host
= (AS_Host
*) SCpnt
->device
->host
->hostdata
;
2695 host
->stats
.aborts
+= 1;
2697 #if (DEBUG & DEBUG_ABORT)
2700 asr
= sbic_arm_read(host
, SBIC_ASR
);
2701 ssr
= sbic_arm_read(host
, SBIC_SSR
);
2703 printk(KERN_WARNING
"acornscsi_abort: ");
2704 print_sbic_status(asr
, ssr
, host
->scsi
.phase
);
2705 acornscsi_dumplog(host
, SCpnt
->device
->id
);
2709 printk("scsi%d: ", host
->host
->host_no
);
2711 switch (acornscsi_do_abort(host
, SCpnt
)) {
2713 * We managed to find the command and cleared it out.
2714 * We do not expect the command to be executing on the
2715 * target, but we have set the busylun bit.
2717 case res_success_clear
:
2718 //#if (DEBUG & DEBUG_ABORT)
2721 clear_bit(SCpnt
->device
->id
* 8 + SCpnt
->device
->lun
, host
->busyluns
);
2724 * We found the command, and cleared it out. Either
2725 * the command is still known to be executing on the
2726 * target, or the busylun bit is not set.
2729 //#if (DEBUG & DEBUG_ABORT)
2730 printk("success\n");
2736 * We did find the command, but unfortunately we couldn't
2737 * unhook it from ourselves. Wait some more, and if it
2738 * still doesn't complete, reset the interface.
2741 //#if (DEBUG & DEBUG_ABORT)
2748 * The command could not be found (either because it completed,
2749 * or it got dropped.
2752 case res_not_running
:
2753 acornscsi_dumplog(host
, SCpnt
->device
->id
);
2755 //#if (DEBUG & DEBUG_ABORT)
2756 printk("not running\n");
2765 * Prototype: int acornscsi_reset(struct scsi_cmnd *SCpnt)
2766 * Purpose : reset a command on this host/reset this host
2767 * Params : SCpnt - command causing reset
2768 * Returns : one of SCSI_RESET_ macros
2770 int acornscsi_bus_reset(struct scsi_cmnd
*SCpnt
)
2772 AS_Host
*host
= (AS_Host
*)SCpnt
->device
->host
->hostdata
;
2773 struct scsi_cmnd
*SCptr
;
2775 host
->stats
.resets
+= 1;
2777 #if (DEBUG & DEBUG_RESET)
2781 asr
= sbic_arm_read(host
, SBIC_ASR
);
2782 ssr
= sbic_arm_read(host
, SBIC_SSR
);
2784 printk(KERN_WARNING
"acornscsi_reset: ");
2785 print_sbic_status(asr
, ssr
, host
->scsi
.phase
);
2786 acornscsi_dumplog(host
, SCpnt
->device
->id
);
2790 acornscsi_dma_stop(host
);
2793 * do hard reset. This resets all devices on this host, and so we
2794 * must set the reset status on all commands.
2796 acornscsi_resetcard(host
);
2798 while ((SCptr
= queue_remove(&host
->queues
.disconnected
)) != NULL
)
2804 /*==============================================================================================
2805 * initialisation & miscellaneous support
2809 * Function: char *acornscsi_info(struct Scsi_Host *host)
2810 * Purpose : return a string describing this interface
2811 * Params : host - host to give information on
2812 * Returns : a constant string
2815 char *acornscsi_info(struct Scsi_Host
*host
)
2817 static char string
[100], *p
;
2821 p
+= sprintf(string
, "%s at port %08lX irq %d v%d.%d.%d"
2822 #ifdef CONFIG_SCSI_ACORNSCSI_SYNC
2825 #ifdef CONFIG_SCSI_ACORNSCSI_TAGGED_QUEUE
2828 #ifdef CONFIG_SCSI_ACORNSCSI_LINK
2831 #if (DEBUG & DEBUG_NO_WRITE)
2832 " NOWRITE (" __stringify(NO_WRITE
) ")"
2834 , host
->hostt
->name
, host
->io_port
, host
->irq
,
2835 VER_MAJOR
, VER_MINOR
, VER_PATCH
);
2839 int acornscsi_proc_info(struct Scsi_Host
*instance
, char *buffer
, char **start
, off_t offset
,
2840 int length
, int inout
)
2842 int pos
, begin
= 0, devidx
;
2843 struct scsi_device
*scd
;
2850 host
= (AS_Host
*)instance
->hostdata
;
2852 p
+= sprintf(p
, "AcornSCSI driver v%d.%d.%d"
2853 #ifdef CONFIG_SCSI_ACORNSCSI_SYNC
2856 #ifdef CONFIG_SCSI_ACORNSCSI_TAGGED_QUEUE
2859 #ifdef CONFIG_SCSI_ACORNSCSI_LINK
2862 #if (DEBUG & DEBUG_NO_WRITE)
2863 " NOWRITE (" __stringify(NO_WRITE
) ")"
2865 "\n\n", VER_MAJOR
, VER_MINOR
, VER_PATCH
);
2867 p
+= sprintf(p
, "SBIC: WD33C93A Address: %p IRQ : %d\n",
2868 host
->base
+ SBIC_REGIDX
, host
->scsi
.irq
);
2870 p
+= sprintf(p
, "DMAC: uPC71071 Address: %p IRQ : %d\n\n",
2871 host
->base
+ DMAC_OFFSET
, host
->scsi
.irq
);
2874 p
+= sprintf(p
, "Statistics:\n"
2875 "Queued commands: %-10u Issued commands: %-10u\n"
2876 "Done commands : %-10u Reads : %-10u\n"
2877 "Writes : %-10u Others : %-10u\n"
2878 "Disconnects : %-10u Aborts : %-10u\n"
2879 "Resets : %-10u\n\nLast phases:",
2880 host
->stats
.queues
, host
->stats
.removes
,
2881 host
->stats
.fins
, host
->stats
.reads
,
2882 host
->stats
.writes
, host
->stats
.miscs
,
2883 host
->stats
.disconnects
, host
->stats
.aborts
,
2884 host
->stats
.resets
);
2886 for (devidx
= 0; devidx
< 9; devidx
++) {
2887 unsigned int statptr
, prev
;
2889 p
+= sprintf(p
, "\n%c:", devidx
== 8 ? 'H' : ('0' + devidx
));
2890 statptr
= host
->status_ptr
[devidx
] - 10;
2892 if ((signed int)statptr
< 0)
2893 statptr
+= STATUS_BUFFER_SIZE
;
2895 prev
= host
->status
[devidx
][statptr
].when
;
2897 for (; statptr
!= host
->status_ptr
[devidx
]; statptr
= (statptr
+ 1) & (STATUS_BUFFER_SIZE
- 1)) {
2898 if (host
->status
[devidx
][statptr
].when
) {
2899 p
+= sprintf(p
, "%c%02X:%02X+%2ld",
2900 host
->status
[devidx
][statptr
].irq
? '-' : ' ',
2901 host
->status
[devidx
][statptr
].ph
,
2902 host
->status
[devidx
][statptr
].ssr
,
2903 (host
->status
[devidx
][statptr
].when
- prev
) < 100 ?
2904 (host
->status
[devidx
][statptr
].when
- prev
) : 99);
2905 prev
= host
->status
[devidx
][statptr
].when
;
2910 p
+= sprintf(p
, "\nAttached devices:\n");
2912 shost_for_each_device(scd
, instance
) {
2913 p
+= sprintf(p
, "Device/Lun TaggedQ Sync\n");
2914 p
+= sprintf(p
, " %d/%d ", scd
->id
, scd
->lun
);
2915 if (scd
->tagged_supported
)
2916 p
+= sprintf(p
, "%3sabled(%3d) ",
2917 scd
->simple_tags
? "en" : "dis",
2920 p
+= sprintf(p
, "unsupported ");
2922 if (host
->device
[scd
->id
].sync_xfer
& 15)
2923 p
+= sprintf(p
, "offset %d, %d ns\n",
2924 host
->device
[scd
->id
].sync_xfer
& 15,
2925 acornscsi_getperiod(host
->device
[scd
->id
].sync_xfer
));
2927 p
+= sprintf(p
, "async\n");
2930 if (pos
+ begin
< offset
) {
2935 if (pos
+ begin
> offset
+ length
) {
2936 scsi_device_put(scd
);
2943 *start
= buffer
+ (offset
- begin
);
2944 pos
-= offset
- begin
;
2952 static struct scsi_host_template acornscsi_template
= {
2953 .module
= THIS_MODULE
,
2954 .proc_info
= acornscsi_proc_info
,
2955 .name
= "AcornSCSI",
2956 .info
= acornscsi_info
,
2957 .queuecommand
= acornscsi_queuecmd
,
2958 .eh_abort_handler
= acornscsi_abort
,
2959 .eh_bus_reset_handler
= acornscsi_bus_reset
,
2962 .sg_tablesize
= SG_ALL
,
2964 .use_clustering
= DISABLE_CLUSTERING
,
2965 .proc_name
= "acornscsi",
2968 static int __devinit
2969 acornscsi_probe(struct expansion_card
*ec
, const struct ecard_id
*id
)
2971 struct Scsi_Host
*host
;
2975 ret
= ecard_request_resources(ec
);
2979 host
= scsi_host_alloc(&acornscsi_template
, sizeof(AS_Host
));
2985 ashost
= (AS_Host
*)host
->hostdata
;
2987 ashost
->base
= ecardm_iomap(ec
, ECARD_RES_MEMC
, 0, 0);
2988 ashost
->fast
= ecardm_iomap(ec
, ECARD_RES_IOCFAST
, 0, 0);
2989 if (!ashost
->base
|| !ashost
->fast
)
2992 host
->irq
= ec
->irq
;
2993 ashost
->host
= host
;
2994 ashost
->scsi
.irq
= host
->irq
;
2996 ec
->irqaddr
= ashost
->fast
+ INT_REG
;
2999 ret
= request_irq(host
->irq
, acornscsi_intr
, IRQF_DISABLED
, "acornscsi", ashost
);
3001 printk(KERN_CRIT
"scsi%d: IRQ%d not free: %d\n",
3002 host
->host_no
, ashost
->scsi
.irq
, ret
);
3006 memset(&ashost
->stats
, 0, sizeof (ashost
->stats
));
3007 queue_initialise(&ashost
->queues
.issue
);
3008 queue_initialise(&ashost
->queues
.disconnected
);
3009 msgqueue_initialise(&ashost
->scsi
.msgs
);
3011 acornscsi_resetcard(ashost
);
3013 ret
= scsi_add_host(host
, &ec
->dev
);
3017 scsi_scan_host(host
);
3021 free_irq(host
->irq
, ashost
);
3022 msgqueue_free(&ashost
->scsi
.msgs
);
3023 queue_free(&ashost
->queues
.disconnected
);
3024 queue_free(&ashost
->queues
.issue
);
3026 ecardm_iounmap(ec
, ashost
->fast
);
3027 ecardm_iounmap(ec
, ashost
->base
);
3028 scsi_host_put(host
);
3030 ecard_release_resources(ec
);
3035 static void __devexit
acornscsi_remove(struct expansion_card
*ec
)
3037 struct Scsi_Host
*host
= ecard_get_drvdata(ec
);
3038 AS_Host
*ashost
= (AS_Host
*)host
->hostdata
;
3040 ecard_set_drvdata(ec
, NULL
);
3041 scsi_remove_host(host
);
3044 * Put card into RESET state
3046 writeb(0x80, ashost
->fast
+ PAGE_REG
);
3048 free_irq(host
->irq
, ashost
);
3050 msgqueue_free(&ashost
->scsi
.msgs
);
3051 queue_free(&ashost
->queues
.disconnected
);
3052 queue_free(&ashost
->queues
.issue
);
3053 ecardm_iounmap(ec
, ashost
->fast
);
3054 ecardm_iounmap(ec
, ashost
->base
);
3055 scsi_host_put(host
);
3056 ecard_release_resources(ec
);
3059 static const struct ecard_id acornscsi_cids
[] = {
3060 { MANU_ACORN
, PROD_ACORN_SCSI
},
3064 static struct ecard_driver acornscsi_driver
= {
3065 .probe
= acornscsi_probe
,
3066 .remove
= __devexit_p(acornscsi_remove
),
3067 .id_table
= acornscsi_cids
,
3069 .name
= "acornscsi",
3073 static int __init
acornscsi_init(void)
3075 return ecard_register_driver(&acornscsi_driver
);
3078 static void __exit
acornscsi_exit(void)
3080 ecard_remove_driver(&acornscsi_driver
);
3083 module_init(acornscsi_init
);
3084 module_exit(acornscsi_exit
);
3086 MODULE_AUTHOR("Russell King");
3087 MODULE_DESCRIPTION("AcornSCSI driver");
3088 MODULE_LICENSE("GPL");