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)
63 #undef CONFIG_SCSI_ACORNSCSI_TAGGED_QUEUE
70 #undef CONFIG_SCSI_ACORNSCSI_LINK
81 #define SDTR_PERIOD 125
82 #define DEFAULT_PERIOD 500
91 #define DEBUG (DEBUG_RESET|DEBUG_WRITE|DEBUG_NO_WRITE)
101 #define TIMEOUT_TIME 10
106 #undef CONFIG_ACORNSCSI_CONSTANTS
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>
137 #include <linux/bitops.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)!
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
182 #define DMAC_BUFFER_SIZE 65536
185 #define STATUS_BUFFER_TO_PRINT 24
192 static int acornscsi_reconnect_finish(
AS_Host *
host);
201 #define SBIC_REGIDX 0x2000
202 #define SBIC_REGVAL 0x2004
203 #define DMAC_OFFSET 0x3000
206 #define INT_REG 0x2000
207 #define PAGE_REG 0x3000
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)
243 void acornscsi_dumpdma(
AS_Host *host,
char *where)
248 addr = dmac_address(host);
252 printk(
"scsi%d: %s: DMAC %02x @%06x+%04x msk %02x, ",
253 host->
host->host_no, where,
254 mode, addr, (len + 1) & 0xffff,
257 printk(
"DMA @%06x, ", host->
dma.start_addr);
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)
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);
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;
324 void acornscsi_resetcard(
AS_Host *host)
326 unsigned int i, timeout;
329 host->
card.page_reg = 0x80;
333 acornscsi_csdelay(3);
335 host->
card.page_reg = 0;
349 printk(
"scsi%d: timeout while resetting card\n",
350 host->
host->host_no);
370 printk(
"scsi%d: timeout while resetting card\n",
371 host->
host->host_no);
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);
383 host->
card.page_reg = 0x40;
397 host->
scsi.disconnectable = 0;
401 for (i = 0; i < 8; i++) {
403 host->
device[
i].disconnect_ok = 1;
407 acornscsi_csdelay(25);
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",
443 "reset - advanced mode",
464 "unexpected disconnect",
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 ",
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);
518 printk(
"%c: %3s:", target == 8 ?
'H' :
'0' + target,
519 line == 0 ?
"ph" : line == 1 ?
"ssr" :
"int");
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);
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;
608 datadir_t acornscsi_datadirection(
int command)
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 }
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;
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))
691 unsigned char calc_sync_xfer(
unsigned int period,
unsigned int offset)
693 return sync_xfer_table[round_period(period)].reg_value |
726 if (host->
scsi.disconnectable && 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)));
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",
763 #ifdef CONFIG_SCSI_ACORNSCSI_TAGGED_QUEUE
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;
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;
808 host->
stats.fins += 1;
813 acornscsi_dma_cleanup(host);
815 SCpnt->
result = result << 16 | host->
scsi.SCp.Message << 8 | host->
scsi.SCp.Status;
829 if (host->
scsi.SCp.ptr &&
834 host->
scsi.SCp.scsi_xferred != host->
dma.transferred)
850 if (host->
dma.xfer_done)
863 printk(
KERN_ERR "scsi%d.H: incomplete data transfer detected: result=%08X command=",
866 acornscsi_dumpdma(host,
"done");
867 acornscsi_dumplog(host, SCpnt->
device->id);
875 panic(
"scsi%d.H: null scsi_done function in acornscsi_done", host->
host->host_no);
881 printk(
"scsi%d: null command in acornscsi_done", host->
host->host_no);
900 host->
dma.xfer_done = 1;
914 void acornscsi_data_read(
AS_Host *host,
char *ptr,
917 extern void __acornscsi_in(
void __iomem *,
char *
buf,
int len);
920 page = (start_addr >> 12);
921 offset = start_addr & ((1 << 12) - 1);
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)) {
959 void acornscsi_data_write(
AS_Host *host,
char *ptr,
962 extern void __acornscsi_out(
void __iomem *,
char *
buf,
int len);
965 page = (start_addr >> 12);
966 offset = start_addr & ((1 << 12) - 1);
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)) {
1005 void acornscsi_dma_stop(
AS_Host *host)
1010 #if (DEBUG & DEBUG_DMA)
1011 DBG(host->
SCpnt, acornscsi_dumpdma(host,
"stop"));
1033 #if (DEBUG & DEBUG_NO_WRITE)
1036 host->
host->host_no, acornscsi_target(host));
1049 host->
dma.start_addr = address = host->
dma.free_addr;
1057 acornscsi_data_write(host, host->
scsi.SCp.ptr, host->
dma.start_addr,
1069 #if (DEBUG & DEBUG_DMA)
1070 DBG(host->
SCpnt, acornscsi_dumpdma(host,
"strt"));
1072 host->
dma.xfer_setup = 1;
1085 void acornscsi_dma_cleanup(
AS_Host *host)
1093 if (host->
dma.xfer_required) {
1094 host->
dma.xfer_required = 0;
1096 acornscsi_data_read(host, host->
dma.xfer_ptr,
1097 host->
dma.xfer_start, host->
dma.xfer_length);
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"));
1115 transferred = dmac_address(host) - host->
dma.start_addr;
1116 host->
dma.transferred += transferred;
1119 acornscsi_data_read(host, host->
scsi.SCp.ptr,
1120 host->
dma.start_addr, transferred);
1125 acornscsi_data_updateptr(host, &host->
scsi.SCp, transferred);
1126 #if (DEBUG & DEBUG_DMA)
1127 DBG(host->
SCpnt, acornscsi_dumpdma(host,
"cupo"));
1143 void acornscsi_dma_intr(
AS_Host *host)
1147 #if (DEBUG & DEBUG_DMA)
1148 DBG(host->
SCpnt, acornscsi_dumpdma(host,
"inti"));
1157 transferred = dmac_address(host) - host->
dma.start_addr;
1158 host->
dma.transferred += transferred;
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);
1177 host->
dma.start_addr = address = host->
dma.free_addr;
1185 acornscsi_data_write(host, host->
scsi.SCp.ptr, host->
dma.start_addr,
1196 #if (DEBUG & DEBUG_DMA)
1197 DBG(host->
SCpnt, acornscsi_dumpdma(host,
"into"));
1200 host->
dma.xfer_setup = 0;
1209 acornscsi_abortcmd(host, host->
SCpnt->tag);
1228 void acornscsi_dma_xfer(
AS_Host *host)
1230 host->
dma.xfer_required = 0;
1233 acornscsi_data_read(host, host->
dma.xfer_ptr,
1234 host->
dma.xfer_start, host->
dma.xfer_length);
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"));
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;
1273 #if (DEBUG & (DEBUG_DMA|DEBUG_WRITE))
1274 DBG(host->
SCpnt, acornscsi_dumpdma(host,
"adjo"));
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);
1294 timeout = max_timeout;
1296 sbic_arm_write(host,
SBIC_DATA, bytes[my_ptr++]);
1299 else if (--timeout == 0)
1306 return (timeout == 0) ? -1 : 0;
1315 acornscsi_sendcommand(
AS_Host *host)
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);
1333 void acornscsi_sendmessage(
AS_Host *host)
1339 #if (DEBUG & DEBUG_MESSAGES)
1340 printk(
"scsi%d.%c: sending message ",
1341 host->
host->host_no, acornscsi_target(host));
1344 switch (message_length) {
1348 acornscsi_sbic_wait(host, ASR_DBR, ASR_DBR, 1000,
"sending message 1");
1352 host->
scsi.last_message =
NOP;
1353 #if (DEBUG & DEBUG_MESSAGES)
1362 acornscsi_sbic_wait(host, ASR_DBR, ASR_DBR, 1000,
"sending message 2");
1366 host->
scsi.last_message = msg->
msg[0];
1367 #if (DEBUG & DEBUG_MESSAGES)
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];
1398 host->
scsi.last_message |= msg->
msg[2] << 8;
1405 #if (DEBUG & DEBUG_MESSAGES)
1416 void acornscsi_readstatusbyte(
AS_Host *host)
1419 acornscsi_sbic_wait(host, ASR_DBR, ASR_DBR, 1000,
"reading status byte");
1429 unsigned char acornscsi_readmessagebyte(
AS_Host *host)
1435 acornscsi_sbic_wait(host, ASR_DBR, ASR_DBR, 1000,
"for message byte");
1437 message = sbic_arm_read(host,
SBIC_DATA);
1440 acornscsi_sbic_wait(host, ASR_INT, ASR_INT, 1000,
"for interrupt after message byte");
1453 void acornscsi_message(
AS_Host *host)
1456 unsigned int msgidx = 0,
msglen = 1;
1459 message[msgidx] = acornscsi_readmessagebyte(host);
1464 (message[0] >= 0x20 && message[0] <= 0x2f))
1470 msglen += message[msgidx];
1478 acornscsi_sbic_wait(host, ASR_INT, ASR_INT, 1000,
"for interrupt after negate ack");
1481 }
while (msgidx <
msglen);
1483 #if (DEBUG & DEBUG_MESSAGES)
1484 printk(
"scsi%d.%c: message in: ",
1485 host->
host->host_no, acornscsi_target(host));
1498 host->
scsi.reconnected.tag = message[1];
1499 if (acornscsi_reconnect_finish(host))
1503 switch (message[0]) {
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);
1513 host->
scsi.SCp.Message = message[0];
1523 acornscsi_dma_cleanup(host);
1525 host->
SCpnt->SCp.sent_command = 0;
1539 acornscsi_dma_cleanup(host);
1554 acornscsi_dma_cleanup(host);
1576 switch (host->
scsi.last_message) {
1577 #ifdef CONFIG_SCSI_ACORNSCSI_TAGGED_QUEUE
1588 host->
host->host_no, acornscsi_target(host));
1589 host->
SCpnt->device->simple_tags = 0;
1598 host->
host->host_no, acornscsi_target(host));
1615 printk(
"scsi%d.%c: reconnect queue tag %02X\n",
1616 host->
host->host_no, acornscsi_target(host),
1621 switch (message[2]) {
1622 #ifdef CONFIG_SCSI_ACORNSCSI_SYNC
1633 host->
host->host_no, acornscsi_target(host),
1634 message[4], message[3] * 4);
1636 calc_sync_xfer(message[3] * 4, message[4]);
1649 calc_sync_xfer(period * 4, length);
1671 #ifdef CONFIG_SCSI_ACORNSCSI_LINK
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);
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);
1694 acornscsi_dma_cleanup(host);
1708 printk(
KERN_ERR "scsi%d.%c: unrecognised message %02X, rejecting\n",
1709 host->
host->host_no, acornscsi_target(host),
1726 void acornscsi_buildmessages(
AS_Host *host)
1738 host->
SCpnt->device->lun));
1743 acornscsi_abortcmd(host->
SCpnt->tag);
1748 #ifdef CONFIG_SCSI_ACORNSCSI_TAGGED_QUEUE
1749 if (host->
SCpnt->tag) {
1762 #ifdef CONFIG_SCSI_ACORNSCSI_SYNC
1779 int acornscsi_starttransfer(
AS_Host *host)
1783 if (!host->
scsi.SCp.ptr ) {
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;
1811 int acornscsi_reconnect(
AS_Host *host)
1819 "- device fault?\n",
1820 host->
host->host_no);
1824 if (host->
SCpnt && !host->
scsi.disconnectable) {
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;
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)
1851 "to reconnect with\n",
1852 host->
host->host_no,
'0' + target);
1853 acornscsi_dumplog(host, target);
1854 acornscsi_abortcmd(host, 0);
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))
1880 host->
host->host_no, acornscsi_target(host)));
1884 #if (DEBUG & (DEBUG_QUEUES|DEBUG_DISCON))
1886 "to disconnected queue\n",
1887 host->
host->host_no, acornscsi_target(host)));
1894 host->
scsi.reconnected.target,
1895 host->
scsi.reconnected.lun,
1896 host->
scsi.reconnected.tag);
1897 #if (DEBUG & (DEBUG_QUEUES|DEBUG_DISCON))
1899 host->
host->host_no, acornscsi_target(host)));
1904 acornscsi_abortcmd(host, host->
scsi.reconnected.tag);
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;
1930 void acornscsi_disconnect_unexpected(
AS_Host *host)
1933 host->
host->host_no, acornscsi_target(host));
1934 #if (DEBUG & DEBUG_ABORT)
1935 acornscsi_dumplog(host, 8);
1948 void acornscsi_abortcmd(
AS_Host *host,
unsigned char tag)
1954 #ifdef CONFIG_SCSI_ACORNSCSI_TAGGED_QUEUE
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);
1990 if (host->
SCpnt && !host->
scsi.disconnectable)
1995 printk(
KERN_ERR "scsi%d: reset in standard mode but wanted advanced mode.\n",
1996 host->
host->host_no);
2011 acornscsi_disconnect_unexpected(host);
2015 switch (host->
scsi.phase) {
2022 host->
dma.transferred = host->
scsi.SCp.scsi_xferred;
2024 asr = sbic_arm_read(host,
SBIC_ASR);
2025 if (!(asr & ASR_INT))
2027 ssr = sbic_arm_read(host,
SBIC_SSR);
2042 acornscsi_reconnect(host);
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);
2059 acornscsi_sendcommand(host);
2064 acornscsi_readstatusbyte(host);
2072 acornscsi_buildmessages(host);
2073 acornscsi_sendmessage(host);
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);
2098 acornscsi_sendcommand(host);
2104 acornscsi_readstatusbyte(host);
2110 acornscsi_sendmessage(host);
2116 acornscsi_message(host);
2121 host->
host->host_no, acornscsi_target(host), ssr);
2122 acornscsi_dumplog(host, host->
SCpnt ? host->
SCpnt->device->id : 8);
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);
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);
2150 acornscsi_readstatusbyte(host);
2156 acornscsi_sendmessage(host);
2161 acornscsi_message(host);
2166 host->
host->host_no, acornscsi_target(host), ssr);
2167 acornscsi_dumplog(host, host->
SCpnt ? host->
SCpnt->device->id : 8);
2173 host->
scsi.disconnectable = 1;
2174 host->
scsi.reconnected.tag = 0;
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);
2186 acornscsi_reconnect(host);
2189 host->
host->host_no, acornscsi_target(host), ssr);
2190 acornscsi_dumplog(host, host->
SCpnt ? host->
SCpnt->device->id : 8);
2203 if (ssr != 0x8f && !acornscsi_reconnect_finish(host))
2210 acornscsi_dma_setup(host,
DMA_OUT);
2211 if (!acornscsi_starttransfer(host))
2212 acornscsi_abortcmd(host, host->
SCpnt->tag);
2219 acornscsi_dma_setup(host,
DMA_IN);
2220 if (!acornscsi_starttransfer(host))
2221 acornscsi_abortcmd(host, host->
SCpnt->tag);
2227 acornscsi_sendcommand(host);
2233 acornscsi_readstatusbyte(host);
2240 acornscsi_sendmessage(host);
2244 acornscsi_message(host);
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);
2262 acornscsi_abortcmd(host, host->
SCpnt->tag);
2269 host->
scsi.SCp.scsi_xferred = scsi_bufflen(host->
SCpnt) -
2270 acornscsi_sbic_xfcount(host);
2271 acornscsi_dma_stop(host);
2272 acornscsi_readstatusbyte(host);
2280 host->
scsi.SCp.scsi_xferred = scsi_bufflen(host->
SCpnt) -
2281 acornscsi_sbic_xfcount(host);
2282 acornscsi_dma_stop(host);
2283 acornscsi_sendmessage(host);
2290 host->
scsi.SCp.scsi_xferred = scsi_bufflen(host->
SCpnt) -
2291 acornscsi_sbic_xfcount(host);
2292 acornscsi_dma_stop(host);
2293 acornscsi_message(host);
2298 host->
host->host_no, acornscsi_target(host), ssr);
2299 acornscsi_dumplog(host, host->
SCpnt ? host->
SCpnt->device->id : 8);
2311 acornscsi_abortcmd(host, host->
SCpnt->tag);
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);
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);
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);
2350 host->
host->host_no, acornscsi_target(host), ssr);
2351 acornscsi_dumplog(host, host->
SCpnt ? host->
SCpnt->device->id : 8);
2360 acornscsi_message(host);
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);
2382 acornscsi_sendmessage(host);
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);
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);
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);
2440 acornscsi_sendmessage(host);
2445 host->
host->host_no, acornscsi_target(host), ssr);
2446 acornscsi_dumplog(host, host->
SCpnt ? host->
SCpnt->device->id : 8);
2452 host->
host->host_no, acornscsi_target(host), ssr);
2453 acornscsi_dumplog(host, host->
SCpnt ? host->
SCpnt->device->id : 8);
2465 acornscsi_intr(
int irq,
void *
dev_id)
2478 acornscsi_dma_intr(host);
2483 ret = acornscsi_sbicintr(host, in_irq);
2490 if (host->
dma.xfer_required)
2491 acornscsi_dma_xfer(host);
2494 ret = acornscsi_kick(host);
2513 static int acornscsi_queuecmd_lck(
struct scsi_cmnd *SCpnt,
2520 panic(
"scsi%d: queuecommand called with NULL done function [cmd=%p]",
2521 host->
host->host_no, SCpnt);
2525 #if (DEBUG & DEBUG_NO_WRITE)
2527 printk(
KERN_CRIT "scsi%d.%c: WRITE attempted with NO_WRITE flag set\n",
2528 host->
host->host_no,
'0' + SCpnt->
device->id);
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;
2557 acornscsi_kick(host);
2586 if (SCpnt == *SCpntp2)
2610 printk(
"on issue queue ");
2622 printk(
"on disconnected queue ");
2625 }
else if (host->
SCpnt == SCpnt) {
2626 unsigned long flags;
2633 switch (host->
scsi.phase) {
2643 if (host->
scsi.disconnectable) {
2644 host->
scsi.disconnectable = 0;
2662 acornscsi_abortcmd(host, host->
SCpnt->tag);
2675 printk(
"waiting for execution ");
2695 host->
stats.aborts += 1;
2700 asr = sbic_arm_read(host,
SBIC_ASR);
2701 ssr = sbic_arm_read(host,
SBIC_SSR);
2704 print_sbic_status(asr, ssr, host->
scsi.phase);
2705 acornscsi_dumplog(host, SCpnt->
device->id);
2711 switch (acornscsi_do_abort(host, SCpnt)) {
2753 acornscsi_dumplog(host, SCpnt->
device->id);
2775 host->
stats.resets += 1;
2781 asr = sbic_arm_read(host,
SBIC_ASR);
2782 ssr = sbic_arm_read(host,
SBIC_SSR);
2785 print_sbic_status(asr, ssr, host->
scsi.phase);
2786 acornscsi_dumplog(host, SCpnt->
device->id);
2790 acornscsi_dma_stop(host);
2796 acornscsi_resetcard(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
2840 int length,
int inout)
2842 int pos, begin = 0, devidx;
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
2867 p +=
sprintf(p,
"SBIC: WD33C93A Address: %p IRQ : %d\n",
2870 p +=
sprintf(p,
"DMAC: uPC71071 Address: %p IRQ : %d\n\n",
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:",
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));
2892 if ((
signed int)statptr < 0)
2895 prev = host->
status[devidx][statptr].when;
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");
2913 p +=
sprintf(p,
"Device/Lun TaggedQ Sync\n");
2916 p +=
sprintf(p,
"%3sabled(%3d) ",
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));
2930 if (pos + begin < offset) {
2935 if (pos + begin > offset + length) {
2943 *start = buffer + (offset - begin);
2944 pos -= offset - begin;
2955 .name =
"AcornSCSI",
2957 .queuecommand = acornscsi_queuecmd,
2965 .proc_name =
"acornscsi",
2985 ashost = (
AS_Host *)host->hostdata;
2989 if (!ashost->
base || !ashost->
fast)
2993 ashost->
host = host;
3011 acornscsi_resetcard(ashost);
3013 ret = scsi_add_host(host, &ec->
dev);
3059 static const struct ecard_id acornscsi_cids[] = {
3065 .probe = acornscsi_probe,
3067 .id_table = acornscsi_cids,
3069 .name =
"acornscsi",
3073 static int __init acornscsi_init(
void)
3078 static void __exit acornscsi_exit(
void)