patch-2.1.110 linux/drivers/acorn/scsi/fas216.c
Next file: linux/drivers/acorn/scsi/fas216.h
Previous file: linux/drivers/acorn/scsi/eesox.c
Back to the patch index
Back to the overall index
- Lines: 208
- Date:
Sat Jul 18 11:55:24 1998
- Orig file:
v2.1.109/linux/drivers/acorn/scsi/fas216.c
- Orig date:
Fri May 8 23:14:47 1998
diff -u --recursive --new-file v2.1.109/linux/drivers/acorn/scsi/fas216.c linux/drivers/acorn/scsi/fas216.c
@@ -22,6 +22,8 @@
* 06-04-1998 RMK Tightened conditions for printing incomplete
* transfers
* 02-05-1998 RMK Added extra checks in fas216_reset
+ * 24-05-1998 RMK Fixed synchronous transfers with period >= 200ns
+ * 27-06-1998 RMK Changed asm/delay.h to linux/delay.h
*
* Todo:
* - tighten up the MESSAGE_REJECT support.
@@ -37,8 +39,8 @@
#include <linux/proc_fs.h>
#include <linux/unistd.h>
#include <linux/stat.h>
+#include <linux/delay.h>
-#include <asm/delay.h>
#include <asm/dma.h>
#include <asm/io.h>
#include <asm/irq.h>
@@ -50,9 +52,12 @@
#include "../../scsi/hosts.h"
#include "fas216.h"
+MODULE_AUTHOR("Russell King");
+MODULE_DESCRIPTION("Generic FAS216/NCR53C9x driver");
+
#define VER_MAJOR 0
#define VER_MINOR 0
-#define VER_PATCH 3
+#define VER_PATCH 4
#define SCSI2_TAG
@@ -81,7 +86,6 @@
*/
#define SCSI2_SYNC
-#undef NO_DISCONNECTS
#undef DEBUG_CONNECT
#undef DEBUG_BUSSERVICE
#undef DEBUG_FUNCTIONDONE
@@ -94,8 +98,7 @@
static void fas216_dumpstate(FAS216_Info *info)
{
- printk("FAS216 registers:\n");
- printk(" CTCL=%02X CTCM=%02X CMD=%02X STAT=%02X"
+ printk("FAS216: CTCL=%02X CTCM=%02X CMD=%02X STAT=%02X"
" INST=%02X IS=%02X CFIS=%02X",
inb(REG_CTCL(info)), inb(REG_CTCM(info)),
inb(REG_CMD(info)), inb(REG_STAT(info)),
@@ -114,7 +117,7 @@
if (used++)
return;
- printk("FAS216_Info = \n");
+ printk("FAS216_Info=\n");
printk(" { magic_start=%lX host=%p SCpnt=%p origSCpnt=%p\n",
info->magic_start, info->host, info->SCpnt,
info->origSCpnt);
@@ -122,17 +125,18 @@
info->scsi.io_port, info->scsi.io_shift, info->scsi.irq,
info->scsi.cfg[0], info->scsi.cfg[1], info->scsi.cfg[2],
info->scsi.cfg[3]);
- printk(" type=%p phase=%X reconnected = { target=%d lun=%d tag=%d }\n",
+ printk(" type=%p phase=%X reconnected={ target=%d lun=%d tag=%d }\n",
info->scsi.type, info->scsi.phase,
info->scsi.reconnected.target,
info->scsi.reconnected.lun, info->scsi.reconnected.tag);
- printk(" SCp = { ptr=%p this_residual=%X buffer=%p buffers_residual=%X }\n",
+ printk(" SCp={ ptr=%p this_residual=%X buffer=%p buffers_residual=%X }\n",
info->scsi.SCp.ptr, info->scsi.SCp.this_residual,
info->scsi.SCp.buffer, info->scsi.SCp.buffers_residual);
printk(" msgs async_stp=%X last_message=%X disconnectable=%d aborting=%d }\n",
info->scsi.async_stp, info->scsi.last_message,
info->scsi.disconnectable, info->scsi.aborting);
- printk(" stats={ queues=%X removes=%X fins=%X reads=%X writes=%X miscs=%X disconnects=%X aborts=%X resets=%X }\n",
+ printk(" stats={ queues=%X removes=%X fins=%X reads=%X writes=%X miscs=%X\n"
+ " disconnects=%X aborts=%X resets=%X }\n",
info->stats.queues, info->stats.removes, info->stats.fins,
info->stats.reads, info->stats.writes, info->stats.miscs,
info->stats.disconnects, info->stats.aborts, info->stats.resets);
@@ -148,7 +152,7 @@
printk(" dma={ transfer_type=%X setup=%p pseudo=%p stop=%p }\n",
info->dma.transfer_type, info->dma.setup,
info->dma.pseudo, info->dma.stop);
- printk(" internal_done=%X magic_end=%lX\n",
+ printk(" internal_done=%X magic_end=%lX }\n",
info->internal_done, info->magic_end);
}
@@ -228,9 +232,9 @@
i = ptr;
- printk(KERN_ERR "SCSI state trail: ");
+ printk(KERN_ERR "SCSI IRQ trail: ");
do {
- printk("%02X:%02X:%02X:%02X ",
+ printk("%02X:%02X:%02X:%1X ",
list[i].stat, list[i].ssr,
list[i].isr, list[i].ph);
i = (i + 1) & 7;
@@ -265,7 +269,8 @@
* : ns - period in ns (between subsequent bytes)
* Returns : Value suitable for REG_STP
*/
-static int fas216_syncperiod(FAS216_Info *info, int ns)
+static int
+fas216_syncperiod(FAS216_Info *info, int ns)
{
int value = (info->ifcfg.clockrate * ns) / 1000;
@@ -279,6 +284,25 @@
return value & 31;
}
+/* Function: void fas216_set_sync(FAS216_Info *info, int target)
+ * Purpose : Correctly setup FAS216 chip for specified transfer period.
+ * Params : info - state structure for interface
+ * : target - target
+ * Notes : we need to switch the chip out of FASTSCSI mode if we have
+ * a transfer period >= 200ns - otherwise the chip will violate
+ * the SCSI timings.
+ */
+static void
+fas216_set_sync(FAS216_Info *info, int target)
+{
+ outb(info->device[target].sof, REG_SOF(info));
+ outb(info->device[target].stp, REG_STP(info));
+ if (info->device[target].period >= (200 / 4))
+ outb(info->scsi.cfg[2] & ~CNTL3_FASTSCSI, REG_CNTL3(info));
+ else
+ outb(info->scsi.cfg[2], REG_CNTL3(info));
+}
+
/* Function: void fas216_updateptrs(FAS216_Info *info, int bytes_transferred)
* Purpose : update data pointers after transfer suspended/paused
* Params : info - interface's local pointer to update
@@ -504,6 +528,8 @@
fas216_updateptrs(info, total - residual);
info->dma.transfer_type = fasdma_none;
}
+ if (info->scsi.phase == PHASE_DATAOUT)
+ outb(CMD_FLUSHFIFO, REG_CMD(info));
}
/* Function: void fas216_disconnected_intr(FAS216_Info *info)
@@ -857,13 +883,13 @@
info->scsi.phase = PHASE_MSGOUT;
case syncneg_sent:
info->device[info->SCpnt->target].negstate = syncneg_complete;
+ info->device[info->SCpnt->target].period = message[3];
info->device[info->SCpnt->target].sof = message[4];
info->device[info->SCpnt->target].stp =
fas216_syncperiod(info, message[3] * 4);
printk(KERN_NOTICE "scsi%d.%c: using synchronous transfer, offset %d, %d ns\n",
info->host->host_no, fas216_target(info), message[4], message[3] * 4);
- outb(info->device[info->SCpnt->target].sof, REG_SOF(info));
- outb(info->device[info->SCpnt->target].stp, REG_STP(info));
+ fas216_set_sync(info, info->SCpnt->target);
break;
}
break;
@@ -1416,8 +1442,7 @@
outb(info->ifcfg.select_timeout, REG_STIM(info));
/* synchronous transfers */
- outb(info->device[SCpnt->target].sof, REG_SOF(info));
- outb(info->device[SCpnt->target].stp, REG_STP(info));
+ fas216_set_sync(info, SCpnt->target);
msglen = msgqueue_msglength(&info->scsi.msgs);
@@ -1742,8 +1767,8 @@
info->stats.aborts += 1;
print_debug_list();
- fas216_dumpinfo(info);
fas216_dumpstate(info);
+ fas216_dumpinfo(info);
printk(KERN_WARNING "scsi%d: fas216_abort: ", info->host->host_no);
do {
@@ -1823,12 +1848,9 @@
#endif
for (i = 0; i < 8; i++) {
-#ifndef NO_DISCONNECTS
- info->device[i].disconnect_ok = 1;
-#else
- info->device[i].disconnect_ok = 0;
-#endif
+ info->device[i].disconnect_ok = info->ifcfg.disconnect_ok;
info->device[i].negstate = negstate;
+ info->device[i].period = info->ifcfg.asyncperiod / 4;
info->device[i].stp = info->scsi.async_stp;
info->device[i].sof = 0;
}
@@ -1979,6 +2001,8 @@
queue_free(&info->queues.issue);
return 1;
}
+
+ outb(CMD_RESETCHIP, REG_CMD(info));
outb(0, REG_CNTL3(info));
outb(CNTL2_S2FE, REG_CNTL2(info));
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov