patch-2.1.91 linux/drivers/scsi/53c7xx.c
Next file: linux/drivers/scsi/53c7xx.h
Previous file: linux/drivers/pci/pci.c
Back to the patch index
Back to the overall index
- Lines: 557
- Date:
Sat Mar 21 11:09:46 1998
- Orig file:
v2.1.90/linux/drivers/scsi/53c7xx.c
- Orig date:
Mon Feb 23 18:12:06 1998
diff -u --recursive --new-file v2.1.90/linux/drivers/scsi/53c7xx.c linux/drivers/scsi/53c7xx.c
@@ -2,7 +2,7 @@
* 53c710 driver. Modified from Drew Eckhardts driver
* for 53c810 by Richard Hirst [richard@sleepie.demon.co.uk]
* Check out PERM_OPTIONS and EXPECTED_CLOCK, which may be defined in the
- * relevant machine specific file (eg. mvme166.[ch], amiga7xx.[ch]).
+ * relevant machine specific file (eg. mvme16x.[ch], amiga7xx.[ch]).
* There are also currently some defines at the top of 53c7xx.scr.
* The chip type is #defined in script_asm.pl, as well as the Makefile.
* Host scsi ID expected to be 7 - see NCR53c7x0_init().
@@ -10,9 +10,9 @@
* I have removed the PCI code and some of the 53c8xx specific code -
* simply to make this file smaller and easier to manage.
*
- * MVME166 issues:
+ * MVME16x issues:
* Problems trying to read any chip registers in NCR53c7x0_init(), as they
- * may never have been set by 166Bug (eg. If kernel has come in over tftp).
+ * may never have been set by 16xBug (eg. If kernel has come in over tftp).
*/
/*
@@ -45,6 +45,9 @@
* validids:0x?? - Bitmask field that disallows certain ID's.
* - e.g. 0x03 allows ID 0,1
* - 0x1F allows ID 0,1,2,3,4
+ * opthi:n - replace top word of options with 'n'
+ * optlo:n - replace bottom word of options with 'n'
+ * - ALWAYS SPECIFY opthi THEN optlo <<<<<<<<<<
*/
/*
@@ -60,7 +63,7 @@
* out brain damaged main boards.
*
* Other PERM_OPTIONS settings are listed below. Note the actual options
- * required are set in the relevant file (mvme166.c, amiga7xx.c, etc):
+ * required are set in the relevant file (mvme16x.c, amiga7xx.c, etc):
*
* OPTION_NO_ASYNC
* Don't negotiate for asynchronous transfers on the first command
@@ -231,6 +234,9 @@
#endif
#include <linux/config.h>
+
+#include <linux/types.h>
+#include <asm/setup.h>
#include <asm/dma.h>
#include <asm/io.h>
#include <asm/system.h>
@@ -259,11 +265,13 @@
#define NO_IO_SPACE
#endif
-#ifdef CONFIG_MVME166
-#include <asm/mvme166hw.h>
+#ifdef CONFIG_MVME16x
+#include <asm/pgtable.h>
+#include <asm/mvme16xhw.h>
#define BIG_ENDIAN
#define NO_IO_SPACE
+#define VALID_IDS
#endif
#include "scsi.h"
@@ -636,6 +644,7 @@
EXTENDED_MESSAGE, 2 /* length */, EXTENDED_WDTR, 1 /* 2^1 bytes */
};
+#if 0
/*
* Function : struct Scsi_Host *find_host (int host)
*
@@ -734,6 +743,7 @@
hostdata->options &= ~OPTION_DISCONNECT;
return 0;
}
+#endif
/*
* Function : static void NCR53c7x0_driver_init (struct Scsi_Host *host)
@@ -751,10 +761,6 @@
int i, j;
u32 *ncrcurrent;
-flush_cache_all();
-cache_push(virt_to_bus(hostdata->script), flushsize);
-cache_clear(virt_to_bus(hostdata->script), flushsize);
-
for (i = 0; i < 16; ++i) {
hostdata->request_sense[i] = 0;
for (j = 0; j < 8; ++j)
@@ -783,9 +789,9 @@
hostdata->initiate_sdtr = 0;
hostdata->talked_to = 0;
hostdata->idle = 1;
-flush_cache_all();
-cache_push(virt_to_bus(hostdata->script), flushsize);
-cache_clear(virt_to_bus(hostdata->script), flushsize);
+
+ if (!MACH_IS_MVME16x)
+ cache_push(virt_to_bus(hostdata->script), flushsize);
}
/*
@@ -877,18 +883,22 @@
setup_used[--i] = 1;
}
+ if (check_setup_strings("opthi",&flags,&val,buf))
+ hostdata->options = (long long)val << 32;
+ if (check_setup_strings("optlo",&flags,&val,buf))
+ hostdata->options |= val;
NCR53c7x0_local_setup(host);
-
switch (hostdata->chip) {
case 710:
+ case 770:
hostdata->dstat_sir_intr = NCR53c7x0_dstat_sir_intr;
hostdata->init_save_regs = NULL;
hostdata->dsa_fixup = NCR53c7xx_dsa_fixup;
hostdata->init_fixup = NCR53c7x0_init_fixup;
hostdata->soft_reset = NCR53c7x0_soft_reset;
hostdata->run_tests = NCR53c7xx_run_tests;
- expected_clock = hostdata->scsi_clock = 50000000;
+ expected_clock = hostdata->scsi_clock;
expected_id = 7;
break;
default:
@@ -904,7 +914,6 @@
hostdata->NCR53c7xx_msg_abort = ABORT;
hostdata->NCR53c7xx_msg_nop = NOP;
hostdata->NOP_insn = (DCMD_TYPE_TCI|DCMD_TCI_OP_JUMP) << 24;
-
if (expected_mapping == -1 ||
(hostdata->options & (OPTION_MEMORY_MAPPED)) !=
(expected_mapping & OPTION_MEMORY_MAPPED))
@@ -917,6 +926,12 @@
hostdata->istat = ((hostdata->chip / 100) == 8) ?
ISTAT_REG_800 : ISTAT_REG_700;
+/* We have to assume that this may be the first access to the chip, so
+ * we must set EA in DCNTL. */
+
+ NCR53c7x0_write8 (DCNTL_REG, DCNTL_10_EA|DCNTL_10_COM);
+
+
/* Only the ISTAT register is readable when the NCR is running, so make
sure it's halted. */
ncr_halt(host);
@@ -990,7 +1005,7 @@
* On NCR53c700 series chips, DCNTL controls the SCSI clock divisor,
* on 800 series chips, it allows for a totem-pole IRQ driver.
* NOTE saved_dcntl currently overwritten in init function.
- * The value read here may be garbage anyway, MVME166 board at least
+ * The value read here may be garbage anyway, MVME16x board at least
* does not initialise chip if kernel arrived via tftp.
*/
@@ -999,7 +1014,7 @@
/*
* DMODE controls DMA burst length, and on 700 series chips,
* 286 mode and bus width
- * NOTE: On MVME166, chip may have been reset, so this could be a
+ * NOTE: On MVME16x, chip may have been reset, so this could be a
* power-on/reset default value.
*/
hostdata->saved_dmode = NCR53c7x0_read8(hostdata->dmode);
@@ -1053,11 +1068,11 @@
* with another board.
*/
-#ifdef CONFIG_MVME166
- if (request_irq(IRQ_MVME166_SCSI, NCR53c7x0_intr, 0, "SCSI-script", NULL))
+#ifdef CONFIG_MVME16x
+ if (request_irq(IRQ_MVME16x_SCSI, NCR53c7x0_intr, 0, "SCSI-script", NULL))
panic ("Couldn't get SCSI IRQ");
-#ifdef MVME166_INTFLY
- else if (request_irq(IRQ_MVME166_FLY, NCR53c7x0_intr, 0, "SCSI-intfly", NULL))
+#ifdef MVME16x_INTFLY
+ else if (request_irq(IRQ_MVME16x_FLY, NCR53c7x0_intr, 0, "SCSI-intfly", NULL))
panic ("Couldn't get INT_FLY IRQ");
#endif
#else
@@ -1105,10 +1120,9 @@
}
/*
- * Function : static int normal_init(Scsi_Host_Template *tpnt, int board,
- * int chip, u32 base, int io_port, int irq, int dma, int pcivalid,
- * unsigned char pci_bus, unsigned char pci_device_fn,
- * long long options);
+ * Function : static int ncr53c7xx_init(Scsi_Host_Template *tpnt, int board,
+ * int chip, u32 base, int io_port, int irq, int dma,
+ * long long options, int clock);
*
* Purpose : initializes a NCR53c7,8x0 based on base addresses,
* IRQ, and DMA channel.
@@ -1137,6 +1151,7 @@
switch (chip) {
case 710:
+ case 770:
schedule_size = (tpnt->can_queue + 1) * 8 /* JUMP instruction size */;
script_len = NCR53c7xx_script_len;
dsa_len = NCR53c7xx_dsa_len;
@@ -1214,7 +1229,7 @@
/* FIXME : if we ever support an ISA NCR53c7xx based board, we
need to check if the chip is running in a 16 bit mode, and if so
unregister it if it is past the 16M (0x1000000) mark */
-
+
hostdata = (struct NCR53c7x0_hostdata *)
instance->hostdata;
hostdata->size = size;
@@ -1269,6 +1284,7 @@
hostdata->dsa_len = dsa_len;
hostdata->max_cmd_size = max_cmd_size;
hostdata->num_cmds = 1;
+ hostdata->scsi_clock = clock;
/* Initialize single command */
tmp = (hostdata->script + hostdata->script_count);
#ifdef FORCE_DSA_ALIGNMENT
@@ -1393,8 +1409,8 @@
* register. Make sure SCRIPTS start automagically.
*/
-#if defined(CONFIG_MVME166)
- /* We know better what we want than 166Bug does! */
+#if defined(CONFIG_MVME16x)
+ /* We know better what we want than 16xBug does! */
tmp = DMODE_10_BL_8 | DMODE_10_FC2;
#else
tmp = NCR53c7x0_read8(DMODE_REG_10);
@@ -1543,9 +1559,9 @@
printk("scsi%d : NCR code relocated to 0x%lx (virt 0x%p)\n", host->host_no,
virt_to_bus(hostdata->script), hostdata->script);
-flush_cache_all();
-cache_push(virt_to_bus(hostdata->script), flushsize);
-cache_clear(virt_to_bus(hostdata->script), flushsize);
+
+ if (!MACH_IS_MVME16x)
+ cache_push(virt_to_bus(hostdata->script), flushsize);
}
/*
@@ -1599,9 +1615,8 @@
start = virt_to_bus (hostdata->script) + hostdata->E_test_1;
hostdata->state = STATE_RUNNING;
printk ("scsi%d : test 1", host->host_no);
- flush_cache_all();
- cache_push(virt_to_bus(hostdata->script), flushsize);
- cache_clear(virt_to_bus(hostdata->script), flushsize);
+ if (!MACH_IS_MVME16x)
+ cache_push(virt_to_bus(hostdata->script), flushsize);
NCR53c7x0_write32 (DSP_REG, start);
if (hostdata->options & OPTION_DEBUG_TRACE)
NCR53c7x0_write8 (DCNTL_REG, hostdata->saved_dcntl | DCNTL_SSM |
@@ -1695,8 +1710,8 @@
hostdata->test_completed = -1;
start = virt_to_bus(hostdata->script) + hostdata->E_test_2;
hostdata->state = STATE_RUNNING;
- flush_cache_all();
- cache_clear(virt_to_bus(hostdata->script), flushsize);
+ if(!MACH_IS_MVME16x)
+ cache_clear(virt_to_bus(hostdata->script), flushsize);
NCR53c7x0_write32 (DSA_REG, virt_to_bus(dsa));
NCR53c7x0_write32 (DSP_REG, start);
if (hostdata->options & OPTION_DEBUG_TRACE)
@@ -1803,9 +1818,10 @@
patch_abs_32 (cmd->dsa, Ent_dsa_code_template / sizeof(u32),
dsa_temp_addr_dsa_value, virt_to_bus(&cmd->dsa_addr));
-flush_cache_all();
-cache_push(virt_to_bus(hostdata->script), flushsize);
-cache_clear(virt_to_bus(hostdata->script), flushsize);
+ if (!MACH_IS_MVME16x) {
+ cache_push(virt_to_bus(hostdata->script), flushsize);
+ cache_push(virt_to_bus(cmd->dsa), flushsize);
+ }
}
/*
@@ -1988,8 +2004,6 @@
*/
save_flags(flags);
cli();
- flush_cache_all();
- cache_push(virt_to_bus(hostdata->script), flushsize);
dsp = (u32 *) bus_to_virt(NCR53c7x0_read32(DSP_REG));
for (bp = hostdata->breakpoints; bp && bp->address != dsp;
bp = bp->next);
@@ -2258,14 +2272,20 @@
host->hostdata;
u32 dsps,*dsp; /* Argument of the INT instruction */
-flush_cache_all();
-cache_push(virt_to_bus(hostdata->script), flushsize);
-cache_clear(virt_to_bus(hostdata->script), flushsize);
-
NCR53c7x0_local_setup(host);
dsps = NCR53c7x0_read32(DSPS_REG);
dsp = (u32 *) bus_to_virt(NCR53c7x0_read32(DSP_REG));
+ /* RGH 150597: Frig. Commands which fail with Check Condition are
+ * Flagged as successful - hack dsps to indicate check condition */
+#if 0
+ /* RGH 200597: Need to disable for BVME6000, as it gets Check Conditions
+ * and then dies. Seems to handle Check Condition at startup, but
+ * not mid kernel build. */
+ if (dsps == A_int_norm_emulateintfly && c && c->result == 2)
+ dsps = A_int_err_check_condition;
+#endif
+
if (hostdata->options & OPTION_DEBUG_INTR)
printk ("scsi%d : DSPS = 0x%x\n", host->host_no, dsps);
@@ -2870,9 +2890,9 @@
host->host_no, (unsigned) dsps);
return SPECIFIC_INT_PANIC;
}
-flush_cache_all();
-cache_push(virt_to_bus(hostdata->script), flushsize);
-cache_clear(virt_to_bus(hostdata->script), flushsize);
+
+ if (!MACH_IS_MVME16x)
+ flush_cache_all();
}
/*
@@ -2910,7 +2930,7 @@
NCR53c7x0_soft_reset (struct Scsi_Host *host) {
NCR53c7x0_local_declare();
unsigned long flags;
-#ifdef CONFIG_MVME166
+#ifdef CONFIG_MVME16x
volatile unsigned long v;
#endif
struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
@@ -2922,7 +2942,7 @@
/* Disable scsi chip and s/w level 7 ints */
-#ifdef CONFIG_MVME166
+#ifdef CONFIG_MVME16x
v = *(volatile unsigned long *)0xfff4006c;
v &= ~0x8000;
*(volatile unsigned long *)0xfff4006c = v;
@@ -2997,7 +3017,7 @@
SIEN_PAR : 0) | SIEN_700_STO | SIEN_RST | SIEN_UDC |
SIEN_SGE | SIEN_MA);
-#ifdef CONFIG_MVME166
+#ifdef CONFIG_MVME16x
/* Enable scsi chip and s/w level 7 ints */
v = *(volatile unsigned long *)0xfff40080;
@@ -3285,10 +3305,6 @@
patch_dsa_32(tmp->dsa, dsa_next, 0, 0);
patch_dsa_32(tmp->dsa, dsa_cmnd, 0, virt_to_bus(cmd));
-flush_cache_all();
-cache_push(virt_to_bus(hostdata->script), flushsize);
-cache_clear(virt_to_bus(hostdata->script), flushsize);
-
if (hostdata->options & OPTION_DEBUG_SYNCHRONOUS) {
exp_select_indirect = ((1 << cmd->target) << 16) |
@@ -3306,11 +3322,6 @@
patch_dsa_32(tmp->dsa, dsa_select, 0,
hostdata->sync[cmd->target].select_indirect);
-
-flush_cache_all();
-cache_push(virt_to_bus(hostdata->script), flushsize);
-cache_clear(virt_to_bus(hostdata->script), flushsize);
-
/*
* Right now, we'll do the WIDE and SYNCHRONOUS negotiations on
* different commands; although it should be trivial to do them
@@ -3339,10 +3350,6 @@
else if (!(hostdata->talked_to & (1 << cmd->target)) &&
!(hostdata->options & OPTION_NO_ASYNC)) {
-flush_cache_all();
-cache_push(virt_to_bus(hostdata->script), flushsize);
-cache_clear(virt_to_bus(hostdata->script), flushsize);
-
memcpy ((void *) (tmp->select + 1), (void *) async_message,
sizeof(async_message));
patch_dsa_32(tmp->dsa, dsa_msgout, 0, 1 + sizeof(async_message));
@@ -3352,10 +3359,6 @@
else
patch_dsa_32(tmp->dsa, dsa_msgout, 0, 1);
-flush_cache_all();
-cache_push(virt_to_bus(hostdata->script), flushsize);
-cache_clear(virt_to_bus(hostdata->script), flushsize);
-
hostdata->talked_to |= (1 << cmd->target);
tmp->select[0] = (hostdata->options & OPTION_DISCONNECT) ?
IDENTIFY (1, cmd->lun) : IDENTIFY (0, cmd->lun);
@@ -3429,11 +3432,6 @@
* Not bad, not good. We'll see.
*/
-flush_cache_all();
-cache_push(virt_to_bus(hostdata->script), flushsize);
-cache_clear(virt_to_bus(hostdata->script), flushsize);
-
-
for (i = 0; cmd->use_sg ? (i < cmd->use_sg) : !i; cmd_datain += 4,
cmd_dataout += 4, ++i) {
u32 buf = cmd->use_sg ?
@@ -3476,11 +3474,6 @@
}
}
-flush_cache_all();
-cache_push(virt_to_bus(hostdata->script), flushsize);
-cache_clear(virt_to_bus(hostdata->script), flushsize);
-
-
/*
* Install JUMP instructions after the data transfer routines to return
* control to the do_other_transfer routines.
@@ -3515,10 +3508,6 @@
cmd_dataout += 2;
}
-flush_cache_all();
-cache_push(virt_to_bus(hostdata->script), flushsize);
-cache_clear(virt_to_bus(hostdata->script), flushsize);
-
return tmp;
}
@@ -3693,11 +3682,6 @@
i > 0 && ncrcurrent[0] != hostdata->NOP_insn;
--i, ncrcurrent += 2 /* JUMP instructions are two words */);
-
-flush_cache_all();
-cache_push(virt_to_bus(hostdata->script), flushsize);
-cache_clear(virt_to_bus(hostdata->script), flushsize);
-
if (i > 0) {
++hostdata->busy[tmp->target][tmp->lun];
cmd->next = hostdata->running_list;
@@ -3724,15 +3708,15 @@
return;
}
- cache_push(virt_to_bus(cmd->dsa), hostdata->dsa_len);
- cache_push(virt_to_bus(ncrcurrent), sizeof(ncrcurrent));
-
/*
* If the NCR chip is in an idle state, start it running the scheduler
* immediately. Otherwise, signal the chip to jump to schedule as
* soon as it is idle.
*/
+ if (!MACH_IS_MVME16x)
+ flush_cache_all();
+
if (hostdata->idle) {
hostdata->idle = 0;
hostdata->state = STATE_RUNNING;
@@ -4133,7 +4117,7 @@
done = 1;
for (host = first_host; host; host = host->next)
if (host->hostt == the_template
-#if defined(MVME166_INTFLY)
+#if defined(MVME16x_INTFLY)
/* We have two different interrupts pointing
* at this routine, so remove this check */
#else
@@ -4157,7 +4141,7 @@
istat = NCR53c7x0_read8(hostdata->istat);
if ((hostdata->options & OPTION_INTFLY) &&
-#ifdef MVME166_INTFLY
+#ifdef MVME16x_INTFLY
/* the bit is set which indicates an on-the-fly int */
(*(volatile unsigned long *)0xfff40068 & 0x8000))
#else
@@ -4168,7 +4152,7 @@
done = 0;
interrupted = 1;
-#ifdef MVME166_INTFLY
+#ifdef MVME16x_INTFLY
/* clear the INTFLY bit */
*(volatile unsigned long *)0xfff40074 = 0x8000;
#endif
@@ -4345,6 +4329,8 @@
#endif
hostdata->state = STATE_RUNNING;
+ if (!MACH_IS_MVME16x)
+ flush_cache_all();
NCR53c7x0_write32 (DSP_REG, virt_to_bus(hostdata->dsp));
if (hostdata->options & OPTION_DEBUG_TRACE) {
#ifdef CYCLIC_TRACE
@@ -4669,7 +4655,9 @@
where = "non-BMI dynamic DSA code";
action = ACTION_ABORT_PRINT;
}
- } else if (dsp == (hostdata->script + hostdata->E_select_msgout / 4)) {
+ } else if (dsp == (hostdata->script + hostdata->E_select_msgout / 4 + 2)) {
+ /* RGH 290697: Added +2 above, to compensate for the script
+ * instruction which disables the selection timer. */
/* Release ATN */
NCR53c7x0_write8 (SOCL_REG, 0);
switch (sbcl) {
@@ -4751,8 +4739,9 @@
print_insn (host, hostdata->dsp, "", 1);
}
#endif
-
- cache_push(virt_to_bus(hostdata->script), flushsize);
+
+ if (!MACH_IS_MVME16x)
+ cache_push(virt_to_bus(hostdata->script), flushsize);
}
/*
@@ -4826,7 +4815,7 @@
*/
if (retry == NEVER) {
- printk(KERN_ALERT " mail drew@PoohSticks.ORG\n");
+ printk(KERN_ALERT " mail ricahrd@sleepie.demon.co.uk\n");
FATAL (host);
}
}
@@ -5097,7 +5086,7 @@
* FIXME : (void *) cast in virt_to_bus should be unnecessary, because
* it should take const void * as argument.
*/
-#ifndef CONFIG_MVME166
+#ifndef CONFIG_MVME16x
sprintf(buf, "%s0x%lx (virt 0x%p) : 0x%08x 0x%08x (virt 0x%p)",
(prefix ? prefix : ""), virt_to_bus((void *) insn), insn,
insn[0], insn[1], bus_to_virt (insn[1]));
@@ -5110,7 +5099,7 @@
#endif
tmp = buf + strlen(buf);
if ((dcmd & DCMD_TYPE_MASK) == DCMD_TYPE_MMI) {
-#ifndef CONFIG_MVME166
+#ifndef CONFIG_MVME16x
sprintf (tmp, " 0x%08x (virt 0x%p)\n", insn[2],
bus_to_virt(insn[2]));
#else
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov