* [PATCH 2.5.59] sim710: cleanup/remove most cli()'s
@ 2003-02-04 10:23 Rolf Eike Beer
2003-02-04 11:34 ` Christoph Hellwig
` (2 more replies)
0 siblings, 3 replies; 9+ messages in thread
From: Rolf Eike Beer @ 2003-02-04 10:23 UTC (permalink / raw)
To: linux-scsi; +Cc: Richard Hirst
Hi,
the appended patch does the following:
-group all includes (except '#include "scsi_module.c"') together
-add KERN_* to all printk's
-add error checking for call of request_region
-remove most cli() and use spin_lock instead
-move help text to Documentation/scsi/sim710.txt
-add a new debug target for debugging spinlocks
-remove the magic numbers for request_region and release_region and use
SIM710_IOREGION_SIZE instead
-same thing for the driver name
-remove assignement to driver_template.proc_name which is already done before
in sim710.h
I have not broken this into peaces because for all changes (except the first
of course) the corresponding lines are grouped together so it should be clear
what I've done.
A kernel with this modification has booted yesterday and was tested under
heavy loads succesfully.
What has to be done is:
-remove the remaining two cli()
-port this to the new driver model
I'm already working on this but it does not boot until now, so I'll delay this
until it works.
Eike
diff -Naur linux-2.5.59-vanilla/Documentation/scsi/sim710.txt linux-2.5.59-lacon/Documentation/scsi/sim710.txt
--- linux-2.5.59-vanilla/Documentation/scsi/sim710.txt Thu Jan 1 01:00:00 1970
+++ linux-2.5.59-lacon/Documentation/scsi/sim710.txt Tue Feb 4 08:50:59 2003
@@ -0,0 +1,90 @@
+Documentation for "sim710"
+
+1. Contributions
+2. General information
+3. Parameters
+4. Limitations
+
+
+1. Contributions
+
+ * MCA card detection code by Trent McNair.
+ * Fixes to not explicitly nul bss data from Xavier Bestel.
+ * Some multiboard fixes from Rolf Eike Beer.
+ * Auto probing of EISA config space from Trevor Hemsley.
+
+
+2. General information
+
+Various bits of code in this driver have been copied from 53c7,8xx,c,
+which is coyright Drew Eckhardt. The scripts for the SCSI chip are
+compiled with the script compiler written by Drew.
+
+This is a simple driver for the NCR53c710. More complex drivers
+for this chip (e.g. 53c7xx.c) require that the scsi chip be able to
+do DMA block moves between memory and on-chip registers, which can
+be a problem if those registers are in the I/O address space. There
+can also be problems on hardware where the registers are memory
+mapped, if the design is such that memory-to-memory transfers initiated
+by the scsi chip cannot access the chip registers.
+
+This driver is designed to avoid these problems and is intended to
+work with any Intel machines using 53c710 chips, including various
+Compaq and NCR machines. It was initially written for the Tadpole
+TP34V VME board which is 68030 based.
+
+
+3. Parameters
+
+The driver supports boot-time parameters similar to
+ sim710=addr:0x9000,irq:15
+and insmod parameters similar to
+ sim710="addr:0x9000 irq:15"
+
+Multiple controllers can also be set up by command line, provided the
+addr: parameter is specified first for each controller. e.g.
+ sim710="addr:0x9000 irq:15 addr:0x8000 irq:14"
+
+To seperate the different options, ' ', '+', and ',' can be used, except
+that ',' can not be used in module parameters. ' ' can be a pain, because
+it needs to be quoted, which causes problems with some installers.
+The command line above is completely equivalent to
+ sim710="addr:0x9000+irq:15+addr:0x8000+irq:14"
+
+The complete list of options are:
+
+ addr:0x9000 Specifies the base I/O port (or address) of the 53c710.
+ irq:15 Specifies the IRQ number used by the 53c710.
+ debug:0xffff Generates lots of debug output. These are the constants
+ used to specify which type of debugging you want:
+ 0x0000 Nothing
+ 0x0001 Detailed trace of chip halt funtion
+ 0x0002 All chip register read/writes
+ 0x0004 Sync/async negotiation
+ 0x0008 Phase mis-match handling
+ 0x0010 General interrupt trace
+ 0x0020 Selection timeouts
+ 0x0040 Resume addresses for the script
+ 0x0080 Commands and status returned
+ 0x0100 Fixup of scsi addresses
+ 0x0200 Disconnect/reselect handling
+ 0x0400 spin_lock/spin_unlock debugging
+ 0xffff Any and all debug options
+ ignore:0x0a Makes the driver ignore SCSI IDs 0 and 2. This ist just
+ the sum over ( 1 << SCSI ID )
+ nodisc:0x70 Prevents disconnects from IDs 6, 5 and 4.
+ noneg:0x10 Prevents SDTR negotiation on ID 4.
+ disabled:1 Completely disables the driver. When present, overrides
+ all other options.
+
+The driver will auto-probe chip addresses and IRQs now, so typically no
+parameters are needed. Auto-probing of addresses is disabled if any addr:
+parameters are specified. The only option you can use if you want auto-probing
+is debug.
+
+
+4. Limitations
+
+ * Async only
+ * Severely lacking in error recovery
+ * 'debug:' should be per host really.
diff -Naur linux-2.5.59-vanilla/drivers/scsi/Kconfig linux-2.5.59-lacon/drivers/scsi/Kconfig
--- linux-2.5.59-vanilla/drivers/scsi/Kconfig Fri Jan 17 03:22:42 2003
+++ linux-2.5.59-lacon/drivers/scsi/Kconfig Tue Feb 4 11:01:39 2003
@@ -1383,8 +1383,8 @@
avoid these problems and is intended to work with any Intel machines
using 53c710 chips, including various Compaq and NCR machines.
- Please read the comments at the top of the file
- <file:drivers/scsi/sim710.c> for more information.
+ Please read the file <file:Documentation/scsi/sim710.txt> for more
+ information.
If you want to compile this driver as a module ( = code which can be
inserted in and removed from the running kernel whenever you want),
diff -Naur linux-2.5.59-vanilla/drivers/scsi/sim710.c linux-2.5.59-lacon/drivers/scsi/sim710.c
--- linux-2.5.59-vanilla/drivers/scsi/sim710.c Fri Jan 17 03:22:29 2003
+++ linux-2.5.59-lacon/drivers/scsi/sim710.c Mon Feb 3 20:22:19 2003
@@ -3,7 +3,7 @@
*
*----------------------------------------------------------------------------
* This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
+ * it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
@@ -17,66 +17,12 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*----------------------------------------------------------------------------
*
- * MCA card detection code by Trent McNair.
- * Fixes to not explicitly nul bss data from Xavier Bestel.
- * Some multiboard fixes from Rolf Eike Beer.
- * Auto probing of EISA config space from Trevor Hemsley.
- *
- * Various bits of code in this driver have been copied from 53c7,8xx,c,
- * which is coyright Drew Eckhardt. The scripts for the SCSI chip are
- * compiled with the script compiler written by Drew.
- *
- * This is a simple driver for the NCR53c710. More complex drivers
- * for this chip (e.g. 53c7xx.c) require that the scsi chip be able to
- * do DMA block moves between memory and on-chip registers, which can
- * be a problem if those registers are in the I/O address space. There
- * can also be problems on hardware where the registers are memory
- * mapped, if the design is such that memory-to-memory transfers initiated
- * by the scsi chip cannot access the chip registers.
- *
- * This driver is designed to avoid these problems and is intended to
- * work with any Intel machines using 53c710 chips, including various
- * Compaq and NCR machines. It was initially written for the Tadpole
- * TP34V VME board which is 68030 based.
- *
- * The driver supports boot-time parameters similar to
- * sim710=addr:0x9000,irq:15
- * and insmod parameters similar to
- * sim710="addr:0x9000 irq:15"
- *
- * Multiple controllers can also be set up by command line, provided the
- * addr: parameter is specified first for each controller. e.g.
- * sim710="addr:0x9000 irq:15 addr:0x8000 irq:14"
- *
- * To seperate the different options, ' ', '+', and ',' can be used, except
- * that ',' can not be used in module parameters. ' ' can be a pain, because
- * it needs to be quoted, which causes problems with some installers.
- * The command line above is completely equivalent to
- * sim710="addr:0x9000+irq:15+addr:0x8000+irq:14"
- *
- * The complete list of options are:
- *
- * addr:0x9000 Specifies the base I/O port (or address) of the 53C710.
- * irq:15 Specifies the IRQ number used by the 53c710.
- * debug:0xffff Generates lots of debug output.
- * ignore:0x0a Makes the driver ignore SCSI IDs 0 and 2.
- * nodisc:0x70 Prevents disconnects from IDs 6, 5 and 4.
- * noneg:0x10 Prevents SDTR negotiation on ID 4.
- * disabled:1 Completely disables the driver. When present, overrides
- * all other options.
- *
- * The driver will auto-probe chip addresses and IRQs now, so typically no
- * parameters are needed. Auto-probing of addresses is disabled if any addr:
- * parameters are specified.
- *
- * Current limitations:
- *
- * o Async only
- * o Severely lacking in error recovery
- * o 'debug:' should be per host really.
- *
+ * See Documentation/scsi/sim710.txt for more information.
*/
+#define DRV_NAME "sim710"
+#define DRV_DESCR "Simple NCR53c710"
+
#include <linux/config.h>
#include <linux/module.h>
@@ -99,6 +45,16 @@
#include <asm/byteorder.h>
#include <linux/blk.h>
+#include "scsi.h"
+#include "hosts.h"
+#include "sim710.h"
+
+#include <linux/stat.h>
+
+/* The SCSI Script!!! */
+
+#include "sim710_d.h"
+
/* All targets are I/O mapped at the moment */
#define IO_MAPPED
@@ -130,12 +86,6 @@
#endif
-#include "scsi.h"
-#include "hosts.h"
-#include "sim710.h"
-
-#include<linux/stat.h>
-
#define DEBUG
#undef DEBUG_LIMIT_INTS /* Define to 10 to hang driver after 10 ints */
@@ -152,6 +102,7 @@
#define DEB_CMND 0x0080 /* Commands and status returned */
#define DEB_FIXUP 0x0100 /* Fixup of scsi addresses */
#define DEB_DISC 0x0200 /* Disconnect/reselect handling */
+#define DEB_SLOCK 0x0400 /* spin_lock/spin_unlock debugging */
#define DEB_ANY 0xffff /* Any and all debug options */
@@ -167,7 +118,7 @@
*/
#define SCSI_DONE(cmd) { \
- DEB(DEB_CMND, printk("scsi%d: Complete %08x\n", \
+ DEB(DEB_CMND, printk(KERN_DEBUG "scsi%d: Complete %08x\n", \
host->host_no, cmd->result)); \
if (cmd->result) \
hostdata->negotiate |= (1 << cmd->target); \
@@ -178,6 +129,8 @@
#define offsetof(t, m) ((size_t) (&((t *)0)->m))
#endif
+#define SIM710_IOREGION_SIZE 0x40
+
#define STATE_INITIALISED 0
#define STATE_HALTED 1
#define STATE_IDLE 2
@@ -209,10 +162,6 @@
static unsigned int bases[MAXBOARDS]; /* Base addresses of chips */
static unsigned int irq_vectors[MAXBOARDS]; /* IRQ vectors used by chips */
-/* The SCSI Script!!! */
-
-#include "sim710_d.h"
-
/* Now define offsets in the DSA, as (A_dsa_xxx/4) */
#define DSA_SELECT (A_dsa_select/4)
@@ -287,12 +236,14 @@
struct sim710_hostdata *hostdata = (struct sim710_hostdata *)
host->hostdata[0];
- save_flags(flags);
- cli();
- printk("scsi%d: Chip register contents:\n", host->host_no);
- printk(" (script at virt %p, bus %lx)\n",
+ DEB(DEB_SLOCK, printk(KERN_DEBUG "ncr_dump: trying to get spinlock for board at 0x%x\n", host->unique_id));
+ spin_lock_irqsave(host->host_lock, flags);
+ DEB(DEB_SLOCK, printk(KERN_DEBUG "ncr_dump: got spinlock\n"));
+
+ printk(KERN_DEBUG "scsi%d: Chip register contents:\n", host->host_no);
+ printk(KERN_DEBUG " (script at virt %p, bus %lx)\n",
hostdata->script, virt_to_bus(hostdata->script));
- printk(" 00 sien: %02x sdid: %02x scntl1:%02x scntl0:%02x\n"
+ printk(KERN_DEBUG " 00 sien: %02x sdid: %02x scntl1:%02x scntl0:%02x\n"
" 04 socl: %02x sodl: %02x sxfer: %02x scid: %02x\n"
" 08 sbcl: %02x sbdl: %02x sidl: %02x sfbr: %02x\n"
" 0C sstat2:%02x sstat1:%02x sstat0:%02x dstat: %02x\n"
@@ -320,7 +271,8 @@
NCR_read8(DWT_REG), NCR_read8(DIEN_REG), NCR_read8(DMODE_REG),
NCR_read32(ADDER_REG));
- restore_flags(flags);
+ spin_unlock_irqrestore(host->host_lock, flags);
+ DEB(DEB_SLOCK, printk(KERN_DEBUG "ncr_dump: released spinlock\n"));
}
@@ -356,7 +308,7 @@
}
#endif
else if (no_of_boards == 0) {
- printk("sim710: Invalid parameters, addr: must come first\n");
+ printk(KERN_WARNING DRV_NAME ": Invalid parameters, addr: must come first\n");
no_of_boards = -1;
return 1;
}
@@ -368,12 +320,9 @@
opt_nodisc[no_of_boards-1] = val;
else if (!strncmp(cur, "noneg:", 6))
opt_noneg[no_of_boards-1] = val;
- else if (!strncmp(cur, "disabled:", 9)) {
- no_of_boards = -1;
- return 1;
- }
else {
- printk("sim710: unexpected boot option '%.*s'\n", (int)(pc-cur+1), cur);
+ if (strncmp(cur, "disabled:", 9))
+ printk(KERN_WARNING DRV_NAME ": unexpected boot option '%.*s'\n", (int)(pc-cur+1), cur);
no_of_boards = -1;
return 1;
}
@@ -442,8 +391,10 @@
int timeout;
int res = 0;
- save_flags(flags);
- cli();
+ DEB(DEB_SLOCK, printk(KERN_DEBUG "ncr_halt: trying to get spinlock for board at 0x%x\n", host->unique_id));
+ spin_lock_irqsave(host->host_lock, flags);
+ DEB(DEB_SLOCK, printk(KERN_DEBUG "ncr_halt: got spinlock\n"));
+
/* Stage 0 : eat all interrupts
Stage 1 : set ABORT
Stage 2 : eat all but abort interrupts
@@ -453,29 +404,29 @@
*/
for (stage = 0, timeout = 50000; timeout; timeout--) {
if (stage == 1) {
- DEB(DEB_HALT, printk("ncr_halt: writing ISTAT_ABRT\n"));
+ DEB(DEB_HALT, printk(KERN_DEBUG "ncr_halt: writing ISTAT_ABRT\n"));
NCR_write8(ISTAT_REG, ISTAT_ABRT);
++stage;
}
istat = NCR_read8 (ISTAT_REG);
if (istat & ISTAT_SIP) {
- DEB(DEB_HALT, printk("ncr_halt: got ISTAT_SIP, istat=%02x\n", istat));
+ DEB(DEB_HALT, printk(KERN_DEBUG "ncr_halt: got ISTAT_SIP, istat=%02x\n", istat));
tmp = NCR_read8(SSTAT0_REG);
- DEB(DEB_HALT, printk("ncr_halt: got SSTAT0_REG=%02x\n", tmp));
+ DEB(DEB_HALT, printk(KERN_DEBUG "ncr_halt: got SSTAT0_REG=%02x\n", tmp));
} else if (istat & ISTAT_DIP) {
- DEB(DEB_HALT, printk("ncr_halt: got ISTAT_DIP, istat=%02x\n", istat));
+ DEB(DEB_HALT, printk(KERN_DEBUG "ncr_halt: got ISTAT_DIP, istat=%02x\n", istat));
tmp = NCR_read8(DSTAT_REG);
- DEB(DEB_HALT, printk("ncr_halt: got DSTAT_REG=%02x\n", tmp));
+ DEB(DEB_HALT, printk(KERN_DEBUG "ncr_halt: got DSTAT_REG=%02x\n", tmp));
if (stage == 2) {
if (tmp & DSTAT_ABRT) {
- DEB(DEB_HALT, printk("ncr_halt: got DSTAT_ABRT, clearing istat\n"));
+ DEB(DEB_HALT, printk(KERN_DEBUG "ncr_halt: got DSTAT_ABRT, clearing istat\n"));
NCR_write8(ISTAT_REG, 0);
++stage;
} else {
res = 1;
break;
- }
- }
+ }
+ }
}
if (!(istat & (ISTAT_SIP|ISTAT_DIP))) {
if (stage == 0)
@@ -485,7 +436,8 @@
}
udelay(10);
}
- restore_flags(flags);
+ spin_unlock_irqrestore(host->host_lock, flags);
+ DEB(DEB_SLOCK, printk(KERN_DEBUG "ncr_halt: released spinlock\n"));
if (timeout == 0 || res) {
printk(KERN_ALERT "scsi%d: could not halt NCR chip\n", host->host_no);
@@ -514,8 +466,10 @@
{
unsigned long flags;
- save_flags(flags);
- cli();
+ DEB(DEB_SLOCK, printk(KERN_DEBUG "sim710_soft_reset: trying to get spinlock for board at 0x%x\n", host->unique_id));
+ spin_lock_irqsave(host->host_lock, flags);
+ DEB(DEB_SLOCK, printk(KERN_DEBUG "sim710_soft_reset: got spinlock\n"));
+
/*
* Do a soft reset of the chip so that everything is
* reinitialized to the power-on state.
@@ -557,7 +511,8 @@
NCR_write8(SIEN_REG_700,
SIEN_PAR | SIEN_700_STO | SIEN_RST | SIEN_UDC | SIEN_SGE | SIEN_MA);
- restore_flags(flags);
+ spin_unlock_irqrestore(host->host_lock, flags);
+ DEB(DEB_SLOCK, printk(KERN_DEBUG "sim710_soft_reset: released spinlock\n"));
}
@@ -581,9 +536,9 @@
memcpy (hostdata->script, SCRIPT, sizeof(SCRIPT));
for (i = 0; i < PATCHES; i++)
hostdata->script[LABELPATCHES[i]] += isa_virt_to_bus(hostdata->script);
- patch_abs_32 (hostdata->script, 0, reselected_identify,
+ patch_abs_32 (hostdata->script, 0, reselected_identify,
isa_virt_to_bus((void *)&(hostdata->reselected_identify)));
- patch_abs_32 (hostdata->script, 0, msgin_buf,
+ patch_abs_32 (hostdata->script, 0, msgin_buf,
isa_virt_to_bus((void *)&(hostdata->msgin_buf[0])));
patch_abs_32 (hostdata->script, 0, msg_reject,
isa_virt_to_bus((void *)&(hostdata->msg_reject)));
@@ -617,7 +572,7 @@
u32 resume_offset;
if (resa && hostdata->negotiate & (1 << cmd->target)) {
- DEB(DEB_SYNC, printk("scsi%d: Response to host SDTR = %02x %02x\n",
+ DEB(DEB_SYNC, printk(KERN_DEBUG "scsi%d: Response to host SDTR = %02x %02x\n",
host->host_no, hostdata->msgin_buf[3], hostdata->msgin_buf[4]));
/* We always issue an SDTR with the identify, so we must issue
* the CDB next.
@@ -626,7 +581,7 @@
hostdata->negotiate &= ~(1 << cmd->target);
}
else {
- DEB(DEB_SYNC, printk("scsi%d: Target initiated SDTR = %02x %02x\n",
+ DEB(DEB_SYNC, printk(KERN_DEBUG "scsi%d: Target initiated SDTR = %02x %02x\n",
host->host_no, hostdata->msgin_buf[3], hostdata->msgin_buf[4]));
memcpy(targdata->dsa_msgout, async_message, sizeof(async_message));
targdata->dsa[DSA_MSGOUT] = sizeof(async_message);
@@ -659,7 +614,7 @@
if (ddir) {
/* Receive */
- if (synchronous)
+ if (synchronous)
count += (NCR_read8 (SSTAT2_REG) & SSTAT2_FF_MASK) >> SSTAT2_FF_SHIFT;
else
if (NCR_read8 (SSTAT1_REG) & SSTAT1_ILF)
@@ -709,7 +664,7 @@
resume_offset = Ent_reselect;
break;
default:
- printk("scsi%d: Unexpected Illegal Instruction, script[%04x]\n",
+ printk(KERN_WARNING "scsi%d: Unexpected Illegal Instruction, script[%04x]\n",
host->host_no, index);
sim710_errors++;
/* resume_offset is zero, which will cause host reset */
@@ -733,7 +688,7 @@
sbcl = NCR_read8(SBCL_REG) & SBCL_PHASE_MASK;
index = (u32)((u32 *)(isa_bus_to_virt(NCR_read32(DSP_REG))) - hostdata->script);
- DEB(DEB_PMM, printk("scsi%d: Phase mismatch, phase %s (%x) at script[0x%x]\n",
+ DEB(DEB_PMM, printk(KERN_DEBUG "scsi%d: Phase mismatch, phase %s (%x) at script[0x%x]\n",
host->host_no, sbcl_to_phase(sbcl), sbcl, index));
DEB(DEB_PMM, print_command(cmd->cmnd));
@@ -749,18 +704,18 @@
* byte of an identify message, regardless of whether we
* have more bytes to send!
*/
- printk("scsi%d: Unexpected switch to CMDOUT during IDENTIFY\n",
+ printk(KERN_WARNING "scsi%d: Unexpected switch to CMDOUT during IDENTIFY\n",
host->host_no);
resume_offset = Ent_resume_cmd;
}
else if (sbcl == SBCL_PHASE_STATIN) {
/* Some devices do this on parity error, at least */
- printk("scsi%d: Unexpected switch to STATUSIN on initial message out\n",
+ printk(KERN_WARNING "scsi%d: Unexpected switch to STATUSIN on initial message out\n",
host->host_no);
resume_offset = Ent_end_data_trans;
}
else {
- printk("scsi%d: Unexpected phase change to %s on initial msgout\n",
+ printk(KERN_WARNING "scsi%d: Unexpected phase change to %s on initial msgout\n",
host->host_no, sbcl_to_phase(sbcl));
/* resume_offset is zero, which will cause a host reset */
}
@@ -779,14 +734,14 @@
oaddr = targdata->dsa[DSA_DATAIN + sg_id * 2 + 1];
residual = datapath_residual (host);
if (residual)
- printk("scsi%d: Residual count %d on DataIn - NOT expected!!!",
+ printk(KERN_WARNING "scsi%d: Residual count %d on DataIn - NOT expected!!!",
host->host_no, residual);
naddr = NCR_read32(DNAD_REG) - residual;
nlen = (NCR_read32(DBC_REG) & 0x00ffffff) + residual;
- DEB(DEB_PMM, printk("scsi%d: DIN sg %d, old %08x/%08x, new %08x/%08x (%d)\n",
+ DEB(DEB_PMM, printk(KERN_DEBUG "scsi%d: DIN sg %d, old %08x/%08x, new %08x/%08x (%d)\n",
host->host_no, sg_id, oaddr, olen, naddr, nlen, residual));
if (oaddr+olen != naddr+nlen) {
- printk("scsi%d: PMM DIN counts error: 0x%x + 0x%x != 0x%x + 0x%x",
+ printk(KERN_WARNING "scsi%d: PMM DIN counts error: 0x%x + 0x%x != 0x%x + 0x%x",
host->host_no, oaddr, olen, naddr, nlen);
}
else {
@@ -809,10 +764,10 @@
residual = datapath_residual (host);
naddr = NCR_read32(DNAD_REG) - residual;
nlen = (NCR_read32(DBC_REG) & 0x00ffffff) + residual;
- DEB(DEB_PMM, printk("scsi%d: DOUT sg %d, old %08x/%08x, new %08x/%08x (%d)\n",
+ DEB(DEB_PMM, printk(KERN_DEBUG "scsi%d: DOUT sg %d, old %08x/%08x, new %08x/%08x (%d)\n",
host->host_no, sg_id, oaddr, olen, naddr, nlen, residual));
if (oaddr+olen != naddr+nlen) {
- printk("scsi%d: PMM DOUT counts error: 0x%x + 0x%x != 0x%x + 0x%x",
+ printk(KERN_WARNING "scsi%d: PMM DOUT counts error: 0x%x + 0x%x != 0x%x + 0x%x",
host->host_no, oaddr, olen, naddr, nlen);
}
else {
@@ -825,12 +780,12 @@
/* Change to Status In at some random point; probably wants to report a
* parity error or similar.
*/
- printk("scsi%d: Unexpected phase change to STATUSIN at index 0x%x\n",
+ printk(KERN_WARNING "scsi%d: Unexpected phase change to STATUSIN at index 0x%x\n",
host->host_no, index);
resume_offset = Ent_end_data_trans;
}
else {
- printk("scsi%d: Unexpected phase change to %s at index 0x%x\n",
+ printk(KERN_WARNING "scsi%d: Unexpected phase change to %s at index 0x%x\n",
host->host_no, sbcl_to_phase(sbcl), index);
/* resume_offset is zero, which will cause a host reset */
}
@@ -893,7 +848,7 @@
break;
case A_int_data_bad_phase:
sbcl = NCR_read8(SBCL_REG) & SBCL_PHASE_MASK;
- printk("scsi%d: int_data_bad_phase, phase %s (%x)\n",
+ printk(KERN_WARNING "scsi%d: int_data_bad_phase, phase %s (%x)\n",
host->host_no, sbcl_to_phase(sbcl), sbcl);
break;
case A_int_bad_msg1:
@@ -912,7 +867,7 @@
case A_int_not_rej:
default:
sbcl = NCR_read8(SBCL_REG) & SBCL_PHASE_MASK;
- printk("scsi%d: Unimplemented script interrupt: %08x, phase %s\n",
+ printk(KERN_WARNING "scsi%d: Unimplemented script interrupt: %08x, phase %s\n",
host->host_no, dsps, sbcl_to_phase(sbcl));
sim710_errors++;
/* resume_offset is zero, which will cause a host reset */
@@ -929,9 +884,12 @@
struct Scsi_Host *host = dev_id;
unsigned long flags;
+ DEB(DEB_SLOCK, printk(KERN_DEBUG "do_sim710_intr_handle: trying to get spinlock for board at 0x%x\n", host->unique_id));
spin_lock_irqsave(host->host_lock, flags);
+ DEB(DEB_SLOCK, printk(KERN_DEBUG "do_sim710_intr_handle: got spinlock\n"));
sim710_intr_handle(irq, host, regs);
spin_unlock_irqrestore(host->host_lock, flags);
+ DEB(DEB_SLOCK, printk(KERN_DEBUG "do_sim710_intr_handle: released spinlock\n"));
}
@@ -964,15 +922,15 @@
* between accesses to sstat0 and dstat ??? */
dstat = NCR_read8(DSTAT_REG);
}
- DEB(DEB_INTS, printk("scsi%d: Int %d, istat %02x, sstat0 %02x "
+ DEB(DEB_INTS, printk(KERN_DEBUG "scsi%d: Int %d, istat %02x, sstat0 %02x "
"dstat %02x, dsp [%04x], scratch %02x\n",
host->host_no, sim710_intrs, istat, sstat0, dstat,
(u32 *)(isa_bus_to_virt(NCR_read32(DSP_REG))) - hostdata->script,
scratch));
if (scratch & 0x100) {
u8 *p = hostdata->msgin_buf;
-
- DEB(DEB_INTS, printk(" msgin_buf: %02x %02x %02x %02x\n",
+
+ DEB(DEB_INTS, printk(KERN_DEBUG " msgin_buf: %02x %02x %02x %02x\n",
p[0], p[1], p[2], p[3]));
}
if ((dstat & DSTAT_SIR) && dsps == A_int_reselected) {
@@ -985,7 +943,7 @@
int id = 0;
if (!(lcrc & 0x7f)) {
- printk("scsi%d: Reselected with LCRC = %02x\n",
+ printk(KERN_INFO "scsi%d: Reselected with LCRC = %02x\n",
host->host_no, lcrc);
cmd = NULL;
}
@@ -994,13 +952,13 @@
id++;
lcrc >>= 1;
}
- DEB(DEB_DISC, printk("scsi%d: Reselected by ID %d\n",
+ DEB(DEB_DISC, printk(KERN_DEBUG "scsi%d: Reselected by ID %d\n",
host->host_no, id));
if (hostdata->running) {
/* Clear SIGP */
(void)NCR_read8(CTEST2_REG_700);
- DEB(DEB_DISC, printk("scsi%d: Select of %d interrupted "
+ DEB(DEB_DISC, printk(KERN_DEBUG "scsi%d: Select of %d interrupted "
"by reselect from %d (%p)\n",
host->host_no, hostdata->running->target,
id, hostdata->target[id].cur_cmd));
@@ -1016,8 +974,8 @@
cmd = hostdata->running;
if (!cmd) {
- printk("scsi%d: No active command!\n", host->host_no);
- printk("scsi%d: Int %d, istat %02x, sstat0 %02x "
+ printk(KERN_INFO "scsi%d: No active command!\n", host->host_no);
+ printk(KERN_INFO "scsi%d: Int %d, istat %02x, sstat0 %02x "
"dstat %02x, dsp [%04x], scratch %02x, dsps %08x\n",
host->host_no, sim710_intrs, istat, sstat0, dstat,
(u32 *)(isa_bus_to_virt(NCR_read32(DSP_REG))) - hostdata->script,
@@ -1025,20 +983,20 @@
/* resume_offset is zero, which will cause a host reset */
}
else if (sstat0 & SSTAT0_700_STO) {
- DEB(DEB_TOUT, printk("scsi%d: Selection timeout\n", host->host_no));
+ DEB(DEB_TOUT, printk(KERN_DEBUG "scsi%d: Selection timeout\n", host->host_no));
cmd->result = DID_NO_CONNECT << 16;
SCSI_DONE(cmd);
hostdata->target[cmd->target].cur_cmd = NULL;
resume_offset = Ent_reselect;
}
else if (sstat0 & (SSTAT0_SGE|SSTAT0_UDC|SSTAT0_RST|SSTAT0_PAR)) {
- printk("scsi%d: Serious error, sstat0 = %02x\n", host->host_no,
+ printk(KERN_ERR "scsi%d: Serious error, sstat0 = %02x\n", host->host_no,
sstat0);
sim710_errors++;
/* resume_offset is zero, which will cause a host reset */
}
else if (dstat & (DSTAT_BF|DSTAT_ABRT|DSTAT_SSI|DSTAT_WTD)) {
- printk("scsi%d: Serious error, dstat = %02x\n", host->host_no,
+ printk(KERN_ERR "scsi%d: Serious error, dstat = %02x\n", host->host_no,
dstat);
sim710_errors++;
/* resume_offset is zero, which will cause a host reset */
@@ -1055,7 +1013,7 @@
}
else {
sim710_errors++;
- printk("scsi%d: Spurious interrupt!\n", host->host_no);
+ printk(KERN_WARNING "scsi%d: Spurious interrupt!\n", host->host_no);
/* resume_offset is zero, which will cause a host reset */
}
}
@@ -1067,7 +1025,7 @@
}
else
hostdata->state = STATE_BUSY;
- DEB(DEB_RESUME, printk("scsi%d: Resuming at script[0x%x]\n",
+ DEB(DEB_RESUME, printk(KERN_DEBUG "scsi%d: Resuming at script[0x%x]\n",
host->host_no, resume_offset/4));
#ifdef DEBUG_LIMIT_INTS
if (sim710_intrs < DEBUG_LIMIT_INTS)
@@ -1081,7 +1039,7 @@
run_process_issue_queue(hostdata);
}
else {
- printk("scsi%d: Failed to handle interrupt. Failing commands "
+ printk(KERN_ERR "scsi%d: Failed to handle interrupt. Failing commands "
"and resetting SCSI bus and chip\n", host->host_no);
mdelay(1000); /* Give chance to read screen!! */
full_reset(host);
@@ -1098,7 +1056,7 @@
int i, datain, dataout, sg_start;
u32 *dip, *dop, dsa;
- DEB(DEB_CMND, printk("scsi%d: id%d starting ", host->host_no,
+ DEB(DEB_CMND, printk(KERN_DEBUG "scsi%d: id%d starting ", host->host_no,
cmd->target));
DEB(DEB_CMND, print_command(cmd->cmnd));
@@ -1139,7 +1097,7 @@
targdata->dsa[DSA_MSGOUT] = 1;
}
else {
- DEB(DEB_SYNC, printk("scsi%d: Negotiating async transfers "
+ DEB(DEB_SYNC, printk(KERN_DEBUG "scsi%d: Negotiating async transfers "
"for ID %d\n",
host->host_no, cmd->target));
memcpy(targdata->dsa_msgout+1, async_message, sizeof(async_message));
@@ -1301,7 +1259,7 @@
return 0;
}
- DEB(DEB_CMND, printk("scsi%d: id%d queuing ", host->host_no,
+ DEB(DEB_CMND, printk(KERN_DEBUG "scsi%d: id%d queuing ", host->host_no,
cmd->target));
DEB(DEB_CMND, print_command(cmd->cmnd));
@@ -1310,11 +1268,12 @@
cmd->SCp.ptr = NULL;
cmd->SCp.buffer = NULL;
- save_flags(flags);
- cli();
+ DEB(DEB_SLOCK, printk(KERN_DEBUG "sim710_queuecommand: trying to get spinlock for board at 0x%x\n", host->unique_id));
+ spin_lock_irqsave(host->host_lock, flags);
+ DEB(DEB_SLOCK, printk(KERN_DEBUG "sim710_queuecommand: got spinlock\n"));
if (ignore_ids[hostdata->chip] & (1 << cmd->target)) {
- printk("scsi%d: ignoring target %d\n", host->host_no, cmd->target);
+ printk(KERN_INFO "scsi%d: ignoring target %d\n", host->host_no, cmd->target);
cmd->result = (DID_BAD_TARGET << 16);
done(cmd);
restore_flags (flags);
@@ -1339,7 +1298,8 @@
tmp = (Scsi_Cmnd *) tmp->SCp.ptr);
tmp->SCp.ptr = (unsigned char *) cmd;
}
- restore_flags (flags);
+ spin_unlock_irqrestore(host->host_lock, flags);
+ DEB(DEB_SLOCK, printk(KERN_DEBUG "sim710_queuecommand: released spinlock\n"));
run_process_issue_queue(hostdata);
return 0;
}
@@ -1371,7 +1331,7 @@
#endif
if (no_of_boards < 0) {
- printk("sim710: NCR53C710 driver disabled\n");
+ printk(KERN_INFO DRV_NAME ": NCR53C710 driver disabled\n");
return 0;
}
@@ -1436,7 +1396,7 @@
irq_vectors[no_of_boards] =
irq_01bb_by_pos[((pos[0] & 0xC0) >> 6)];
if (bases[no_of_boards] == 0x0000)
- printk("sim710: NCR53C710 Adapter ID 0x01bb is disabled.\n");
+ printk(KERN_INFO DRV_NAME ": NCR53C710 Adapter ID 0x01bb is disabled.\n");
else {
no_of_boards++;
if ( *id_to_check == 0x01bb )
@@ -1452,7 +1412,7 @@
irq_vectors[no_of_boards] =
irq_004f_by_pos[((pos[0] & 0x70) >> 4) - 4];
if (bases[no_of_boards] == 0x0000)
- printk("sim710: NCR53C710 Adapter ID 0x004f is disabled.\n");
+ printk(KERN_INFO DRV_NAME ": NCR53C710 Adapter ID 0x004f is disabled.\n");
else {
no_of_boards++;
mca_set_adapter_name(slot,
@@ -1470,8 +1430,8 @@
if (no_of_boards == 0) {
int io_addr;
/* reverse probe, so my on-board controller at 0x9000 is always scsi0 */
- for (io_addr = 0x9000; no_of_boards < MAXBOARDS && io_addr >= 0x1000; io_addr -= 0x1000) {
- if (request_region(io_addr, 0x40, "sim710") != NULL) {
+ for (io_addr = 0x9000; no_of_boards < MAXBOARDS && io_addr > 0x0000; io_addr -= 0x1000) {
+ if (request_region(io_addr, SIM710_IOREGION_SIZE, DRV_NAME) != NULL) {
int id0 = inw(io_addr + 0xc80);
int id1 = inw(io_addr + 0xc82);
/* The on-board controller on my Proliant 2000 is 0x1044,
@@ -1501,19 +1461,19 @@
irq_vectors[no_of_boards] = 9;
break;
default:
- printk("sim710.c: irq nasty\n");
+ printk(KERN_WARNING DRV_NAME ": irq nasty\n");
}
#endif
no_of_boards++;
}
- release_region(io_addr, 64);
+ release_region(io_addr, SIM710_IOREGION_SIZE);
}
}
}
#endif
-
+
if (!no_of_boards) {
- printk("sim710: No NCR53C710 adapter found.\n");
+ printk(KERN_INFO DRV_NAME ": No NCR53C710 adapter found.\n");
return 0;
}
@@ -1523,17 +1483,17 @@
hostdata_order++;
size = PAGE_SIZE << hostdata_order;
- DEB(DEB_ANY, printk("sim710: hostdata %d bytes, size %d, order %d\n",
+ DEB(DEB_ANY, printk(KERN_DEBUG DRV_NAME ": hostdata %d bytes, size %d, order %d\n",
sizeof(struct sim710_hostdata), size, hostdata_order));
- tpnt->proc_name = "sim710";
+ tpnt->proc_name = DRV_NAME;
memset(our_hosts, 0, sizeof(our_hosts));
for (indx = 0; indx < no_of_boards; indx++) {
unsigned long page = __get_free_pages(GFP_ATOMIC, hostdata_order);
if(page == 0UL)
{
- printk(KERN_WARNING "sim710: out of memory registering board %d.\n", indx);
+ printk(KERN_WARNING DRV_NAME ": out of memory registering board %d.\n", indx);
break;
}
host = scsi_register(tpnt, 4);
@@ -1548,9 +1508,9 @@
scsi_id = 7;
base_addr = bases[indx];
requested_irq = irq_vectors[indx];
- printk("scsi%d: Configuring Sim710 (SCSI-ID %d) at %x, IRQ %d\n",
+ printk(KERN_INFO "scsi%d: Configuring Sim710 (SCSI-ID %d) at 0x%x, IRQ %d\n",
host->host_no, scsi_id, base_addr, requested_irq);
- DEB(DEB_ANY, printk("sim710: hostdata = %p (%d bytes), dsa0 = %p\n",
+ DEB(DEB_ANY, printk(KERN_DEBUG DRV_NAME ": hostdata = %p (%d bytes), dsa0 = %p\n",
hostdata, sizeof(struct sim710_hostdata),
hostdata->target[0].dsa));
hostdata->chip = indx;
@@ -1563,18 +1523,24 @@
if (ncr_halt(host)) {
free_pages(host->hostdata[0], hostdata_order);
scsi_unregister (host);
- printk("scsi%d: Failed to initialise 53c710 at address %x\n",
+ printk(KERN_WARNING "scsi%d: Failed to initialise 53c710 at address 0x%x\n",
host->host_no, base_addr);
continue;
}
DEB(DEB_ANY,ncr_dump(host));
revision = (NCR_read8(CTEST8_REG) & 0xF0) >> 4;
- printk("scsi%d: Revision 0x%x\n",host->host_no,revision);
+ printk(KERN_INFO "scsi%d: Revision 0x%x\n",host->host_no,revision);
sim710_soft_reset(host);
sim710_driver_init(host);
- request_region((u32)host->base, 64, "sim710");
+ if ( ! request_region((u32)host->base, SIM710_IOREGION_SIZE, DRV_NAME) ) {
+ free_pages(host->hostdata[0], hostdata_order);
+ scsi_unregister (host);
+ printk(KERN_WARNING "scsi%d: Failed to request region for NCR53c710 at address 0x%x\n",
+ host->host_no, base_addr);
+ continue;
+ }
/* Now run test1 */
hostdata->test1_src = 0x53c710aa;
hostdata->test1_dst = 0x76543210;
@@ -1591,43 +1557,43 @@
probed_irq = probe_irq_off(irq_mask);
if (requested_irq == 0) {
if (probed_irq > 0) {
- printk("scsi%d: Chip is using IRQ %d\n", host->host_no,
+ printk(KERN_INFO "scsi%d: Chip is using IRQ %d\n", host->host_no,
probed_irq);
requested_irq = host->irq = probed_irq;
}
else {
- printk("scsi%d: Failed to probe for IRQ (returned %d)\n",
+ printk(KERN_WARNING "scsi%d: Failed to probe for IRQ (returned %d)\n",
host->host_no, probed_irq);
ncr_halt(host);
free_pages(host->hostdata[0], hostdata_order);
scsi_unregister (host);
- release_region((u32)host->base, 64);
+ release_region((u32)host->base, SIM710_IOREGION_SIZE);
continue;
}
}
else if (probed_irq > 0 && probed_irq != requested_irq)
- printk("scsi%d: WARNING requested IRQ %d, but probed as %d\n",
+ printk(KERN_WARNING "scsi%d: WARNING requested IRQ %d, but probed as %d\n",
host->host_no, requested_irq, probed_irq);
else if (probed_irq <= 0)
- printk("scsi%d: WARNING IRQ probe failed, (returned %d)\n",
+ printk(KERN_WARNING "scsi%d: WARNING IRQ probe failed, (returned %d)\n",
host->host_no, probed_irq);
-
+
dsps = NCR_read32(DSPS_REG);
if (hostdata->test1_dst != 0x53c710aa || dsps != A_int_test1) {
if (hostdata->test1_dst != 0x53c710aa)
- printk("scsi%d: test 1 FAILED: data: exp 0x53c710aa, got 0x%08x\n",
+ printk(KERN_WARNING "scsi%d: test 1 FAILED: data: exp 0x53c710aa, got 0x%08x\n",
host->host_no, hostdata->test1_dst);
if (dsps != A_int_test1)
- printk("scsi%d: test 1 FAILED: dsps: exp 0x%08x, got 0x%08x\n",
+ printk(KERN_WARNING "scsi%d: test 1 FAILED: dsps: exp 0x%08x, got 0x%08x\n",
host->host_no, A_int_test1, dsps);
ncr_dump(host);
ncr_halt(host);
free_pages(host->hostdata[0], hostdata_order);
scsi_unregister (host);
- release_region((u32)host->base, 64);
+ release_region((u32)host->base, SIM710_IOREGION_SIZE);
continue;
}
- printk("scsi%d: test 1 completed ok.\n", host->host_no);
+ printk(KERN_INFO "scsi%d: test 1 completed ok.\n", host->host_no);
NCR_write32(DSP_REG, virt_to_bus(hostdata->script+Ent_reselect/4));
hostdata->state = STATE_IDLE;
@@ -1641,7 +1607,7 @@
if (request_irq(host->irq, do_sim710_intr_handle,
SA_INTERRUPT | SA_SHIRQ, "sim710", host))
{
- printk("scsi%d : IRQ%d not free, detaching\n",
+ printk(KERN_WARNING "scsi%d : IRQ%d not free, detaching\n",
host->host_no, host->irq);
ncr_halt(host);
free_pages(host->hostdata[0], hostdata_order);
@@ -1658,7 +1624,7 @@
{
struct Scsi_Host * host = cmd->host;
- printk("scsi%d: Unable to abort command for target %d\n",
+ printk(KERN_ERR "scsi%d: Unable to abort command for target %d\n",
host->host_no, cmd->target);
return FAILED;
}
@@ -1672,7 +1638,7 @@
{
struct Scsi_Host * host = SCpnt->host;
- printk("scsi%d: Unable to send Bus Device Reset for target %d\n",
+ printk(KERN_ERR "scsi%d: Unable to send Bus Device Reset for target %d\n",
host->host_no, SCpnt->target);
return FAILED;
}
@@ -1686,7 +1652,7 @@
{
struct Scsi_Host * host = SCpnt->host;
- printk("scsi%d: Unable to do SCSI bus reset\n", host->host_no);
+ printk(KERN_ERR "scsi%d: Unable to do SCSI bus reset\n", host->host_no);
return FAILED;
}
@@ -1701,8 +1667,9 @@
u32 istat, dstat = 0, sstat0 = 0, sstat1 = 0, dsp, dsps, scratch;
unsigned long flags;
- save_flags(flags);
- cli();
+ DEB(DEB_SLOCK, printk(KERN_DEBUG "full_reset: trying to get spinlock for board at 0x%x\n", host->unique_id));
+ spin_lock_irqsave(host->host_lock, flags);
+ DEB(DEB_SLOCK, printk(KERN_DEBUG "full_reset: got spinlock\n"));
istat = NCR_read8(ISTAT_REG);
if (istat & ISTAT_SIP) {
@@ -1717,19 +1684,20 @@
restore_flags(flags);
return FAILED;
}
- restore_flags(flags);
+ spin_unlock_irqrestore(host->host_lock, flags);
+ DEB(DEB_SLOCK, printk(KERN_DEBUG "full_reset: released spinlock\n"));
dsp = NCR_read32(DSP_REG);
dsps = NCR_read32(DSPS_REG);
scratch = NCR_read32(SCRATCH_REG);
- printk("scsi%d: istat = %02x, sstat0 = %02x, sstat1 = %02x, dstat = %02x\n",
+ printk(KERN_INFO "scsi%d: istat = %02x, sstat0 = %02x, sstat1 = %02x, dstat = %02x\n",
host->host_no, istat, sstat0, sstat1, dstat);
- printk("scsi%d: dsp = %08x (script[0x%04x]), dsps = %08x, scratch = %08x\n",
+ printk(KERN_INFO "scsi%d: dsp = %08x (script[0x%04x]), dsps = %08x, scratch = %08x\n",
host->host_no, dsp,
((u32)bus_to_virt(dsp) - (u32)hostdata->script)/4, dsps, scratch);
for (target = 0; target < 7; target++) {
if ((cmd = hostdata->target[target].cur_cmd)) {
- printk("scsi%d: Failing command for ID%d\n",
+ printk(KERN_WARNING "scsi%d: Failing command for ID%d\n",
host->host_no, target);
cmd->result = DID_RESET << 16;
cmd->scsi_done(cmd);
@@ -1757,7 +1725,7 @@
{
struct Scsi_Host * host = SCpnt->host;
- printk("scsi%d: >>>>>>>>>>>> Host reset <<<<<<<<<<<<\n", host->host_no);
+ printk(KERN_INFO "scsi%d: >>>>>>>>>>>> Host reset <<<<<<<<<<<<\n", host->host_no);
return full_reset(host);
}
@@ -1770,7 +1738,7 @@
ncr_halt(host);
free_pages(host->hostdata[0], hostdata_order);
free_irq(host->irq, host);
- release_region((u32)host->base, 64);
+ release_region((u32)host->base, SIM710_IOREGION_SIZE);
return 1;
}
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH 2.5.59] sim710: cleanup/remove most cli()'s
2003-02-04 10:23 [PATCH 2.5.59] sim710: cleanup/remove most cli()'s Rolf Eike Beer
@ 2003-02-04 11:34 ` Christoph Hellwig
2003-02-04 23:11 ` James Bottomley
2003-02-05 15:03 ` Rolf Eike Beer
2 siblings, 0 replies; 9+ messages in thread
From: Christoph Hellwig @ 2003-02-04 11:34 UTC (permalink / raw)
To: Rolf Eike Beer; +Cc: linux-scsi, Richard Hirst
> +#include <linux/stat.h>
I don't think this is actually needed.
And once you're at it. please make all host_template methods static,
remove the prototypes in sim710.h and initialize the driver template
directly in sim710.c instead of the pre-2.4 header magic.
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH 2.5.59] sim710: cleanup/remove most cli()'s
2003-02-04 10:23 [PATCH 2.5.59] sim710: cleanup/remove most cli()'s Rolf Eike Beer
2003-02-04 11:34 ` Christoph Hellwig
@ 2003-02-04 23:11 ` James Bottomley
2003-02-05 15:03 ` Rolf Eike Beer
2 siblings, 0 replies; 9+ messages in thread
From: James Bottomley @ 2003-02-04 23:11 UTC (permalink / raw)
To: Rolf Eike Beer; +Cc: SCSI Mailing List, Richard Hirst
On Tue, 2003-02-04 at 04:23, Rolf Eike Beer wrote:
> Hi,
>
> the appended patch does the following:
>
> -group all includes (except '#include "scsi_module.c"') together
> -add KERN_* to all printk's
> -add error checking for call of request_region
> -remove most cli() and use spin_lock instead
> -move help text to Documentation/scsi/sim710.txt
> -add a new debug target for debugging spinlocks
> -remove the magic numbers for request_region and release_region and use
> SIM710_IOREGION_SIZE instead
> -same thing for the driver name
> -remove assignement to driver_template.proc_name which is already done before
> in sim710.h
>
> I have not broken this into peaces because for all changes (except the first
> of course) the corresponding lines are grouped together so it should be clear
> what I've done.
>
> A kernel with this modification has booted yesterday and was tested under
> heavy loads succesfully.
>
> What has to be done is:
> -remove the remaining two cli()
> -port this to the new driver model
>
> I'm already working on this but it does not boot until now, so I'll delay this
> until it works.
Actually, since you're showing an interest in this driver, I think the
best thing to do would be to port it to use the 53c700 chip driver.
Since the 53c700 already has all the sti/cli and DMA API issues sorted
out already, the only thing that would need to be done is to convert
sim710 to a template that speaks the new device model and initialises
the chip fields.
This would also bring synchronous operation and tag command queueing
virtually for free.
James
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH 2.5.59] sim710: cleanup/remove most cli()'s
2003-02-04 10:23 [PATCH 2.5.59] sim710: cleanup/remove most cli()'s Rolf Eike Beer
2003-02-04 11:34 ` Christoph Hellwig
2003-02-04 23:11 ` James Bottomley
@ 2003-02-05 15:03 ` Rolf Eike Beer
2003-02-06 16:35 ` James Bottomley
2003-02-07 7:26 ` Rolf Eike Beer
2 siblings, 2 replies; 9+ messages in thread
From: Rolf Eike Beer @ 2003-02-05 15:03 UTC (permalink / raw)
To: linux-scsi
Hi again,
I'm now looking for the best way to port this to use 53c700.c. This will
surely take a while, should I fix my fix and resend it or better leave this
unfixed until I find time to port it?
For today this fix should be enough. The second one is unneeded because
mca_register_driver does it.
Eike
Note: Please CC me, I'm not ...
--- linux-2.5.59-test/drivers/scsi/53c700.c Fri Jan 17 03:21:40 2003
+++ linux-2.5.59/drivers/scsi/53c700.c Wed Feb 5 15:47:00 2003
@@ -1769,7 +1769,7 @@
NCR_700_set_depth(SCp->device, NCR_700_get_depth(SCp->device) + 1);
/* begin the command here */
- /* no need to check for NULL, test for command_slot_cound above
+ /* no need to check for NULL, test for command_slot_count above
* ensures a slot is free */
slot = find_empty_slot(hostdata);
--- linux-2.5.59-test/drivers/scsi/NCR_D700.c Fri Jan 17 03:21:39 2003
+++ linux-2.5.59/drivers/scsi/NCR_D700.c Wed Feb 5 15:47:02 2003
@@ -340,7 +340,6 @@
.id_table = NCR_D700_id_table,
.driver = {
.name = "NCR_D700",
- .bus = &mca_bus_type,
.probe = NCR_D700_probe,
},
};
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH 2.5.59] sim710: cleanup/remove most cli()'s
2003-02-05 15:03 ` Rolf Eike Beer
@ 2003-02-06 16:35 ` James Bottomley
2003-02-07 7:26 ` Rolf Eike Beer
1 sibling, 0 replies; 9+ messages in thread
From: James Bottomley @ 2003-02-06 16:35 UTC (permalink / raw)
To: Rolf Eike Beer; +Cc: SCSI Mailing List
On Wed, 2003-02-05 at 09:03, Rolf Eike Beer wrote:
> Hi again,
>
> I'm now looking for the best way to port this to use 53c700.c. This will
> surely take a while, should I fix my fix and resend it or better leave this
> unfixed until I find time to port it?
Do you actually have one of these (and is it EISA or MCA)?
I've got a MCA 710 in an old NCR3430 I can use. I think the conversion
will only take a few days, I can try it out
> For today this fix should be enough. The second one is unneeded because
> mca_register_driver does it.
>
> Eike
>
> Note: Please CC me, I'm not ...
>
> --- linux-2.5.59-test/drivers/scsi/53c700.c Fri Jan 17 03:21:40 2003
> +++ linux-2.5.59/drivers/scsi/53c700.c Wed Feb 5 15:47:00 2003
> @@ -1769,7 +1769,7 @@
> NCR_700_set_depth(SCp->device, NCR_700_get_depth(SCp->device) + 1);
>
> /* begin the command here */
> - /* no need to check for NULL, test for command_slot_cound above
> + /* no need to check for NULL, test for command_slot_count above
> * ensures a slot is free */
> slot = find_empty_slot(hostdata);
>
> --- linux-2.5.59-test/drivers/scsi/NCR_D700.c Fri Jan 17 03:21:39 2003
> +++ linux-2.5.59/drivers/scsi/NCR_D700.c Wed Feb 5 15:47:02 2003
> @@ -340,7 +340,6 @@
> .id_table = NCR_D700_id_table,
> .driver = {
> .name = "NCR_D700",
> - .bus = &mca_bus_type,
> .probe = NCR_D700_probe,
> },
This is actually required by convention. Just in case we ever move to a
unified driver registration model, it would use the bus type to test on.
James
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH 2.5.59] sim710: cleanup/remove most cli()'s
2003-02-05 15:03 ` Rolf Eike Beer
2003-02-06 16:35 ` James Bottomley
@ 2003-02-07 7:26 ` Rolf Eike Beer
2003-02-08 3:57 ` James Bottomley
1 sibling, 1 reply; 9+ messages in thread
From: Rolf Eike Beer @ 2003-02-07 7:26 UTC (permalink / raw)
To: linux-scsi
>From James Bottomley:
> On Wed, 2003-02-05 at 09:03, Rolf Eike Beer wrote:
>> I'm now looking for the best way to port this to use 53c700.c. This will
>> surely take a while, should I fix my fix and resend it or better leave this
>> unfixed until I find time to port it?
> Do you actually have one of these (and is it EISA or MCA)?
It's a Compaq Prosignia with one onboard and the other one on an EISA card,
using base addresses 0x8000 and 0x7000.
> I've got a MCA 710 in an old NCR3430 I can use. I think the conversion
> will only take a few days, I can try it out
That would be fine, you know your code better than I ever will.
Eike
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH 2.5.59] sim710: cleanup/remove most cli()'s
2003-02-07 7:26 ` Rolf Eike Beer
@ 2003-02-08 3:57 ` James Bottomley
2003-02-11 10:55 ` Rolf Eike Beer
0 siblings, 1 reply; 9+ messages in thread
From: James Bottomley @ 2003-02-08 3:57 UTC (permalink / raw)
To: Rolf Eike Beer; +Cc: SCSI Mailing List
[-- Attachment #1: Type: text/plain, Size: 261 bytes --]
On Fri, 2003-02-07 at 01:26, Rolf Eike Beer wrote:
> That would be fine, you know your code better than I ever will.
OK, the attached works for me for the 3430 MCA internal SCSI chip and an
HP EISA SCSI board. Let me know how it works for the Compaq.
James
[-- Attachment #2: tmp.diff --]
[-- Type: text/plain, Size: 66477 bytes --]
# This is a BitKeeper generated patch for the following project:
# Project Name: Linux kernel tree
# This patch format is intended for GNU patch command version 2.5 or higher.
# This patch includes the following deltas:
# ChangeSet 1.956 -> 1.957
# drivers/scsi/Makefile 1.34 -> 1.35
# drivers/scsi/sim710.c 1.6 -> 1.7
# drivers/scsi/Kconfig 1.9 -> 1.10
#
# The following is the BitKeeper ChangeSet Log
# --------------------------------------------
# 03/02/07 jejb@raven.il.steeleye.com 1.957
# Fix sim710 driver
#
# Make it use the 53c700 chip driver. This should give conversion
# to the DMA API, synchronous operation and tag command queueing
# --------------------------------------------
#
diff -Nru a/drivers/scsi/Kconfig b/drivers/scsi/Kconfig
--- a/drivers/scsi/Kconfig Fri Feb 7 21:52:42 2003
+++ b/drivers/scsi/Kconfig Fri Feb 7 21:52:42 2003
@@ -1372,24 +1372,16 @@
# definitely looks note 64bit safe:
config SCSI_SIM710
tristate "Simple 53c710 SCSI support (Compaq, NCR machines)"
- depends on (ISA || MCA && !X86_64) && SCSI
+ depends on (EISA || MCA && !X86_64) && SCSI
---help---
- This is a simple driver for NCR53c710 based SCSI host adapters.
+ This driver for NCR53c710 based SCSI host adapters.
- More complex drivers for this chip are available ("NCR53c7,8xx SCSI
- support", above), but they require that the scsi chip be able to do
- DMA block moves between memory and on-chip registers, which can
- cause problems under certain conditions. This driver is designed to
- avoid these problems and is intended to work with any Intel machines
- using 53c710 chips, including various Compaq and NCR machines.
+ It currently supports Compaq EISA cards and NCR MCA cards
- Please read the comments at the top of the file
- <file:drivers/scsi/sim710.c> for more information.
-
- If you want to compile this driver as a module ( = code which can be
- inserted in and removed from the running kernel whenever you want),
- say M here and read <file:Documentation/modules.txt>. The module
- will be called sim710.o.
+config 53C700_IO_MAPPED
+ bool
+ depends on SCSI_SIM710
+ default y
config SCSI_SYM53C416
tristate "Symbios 53c416 SCSI support"
diff -Nru a/drivers/scsi/Makefile b/drivers/scsi/Makefile
--- a/drivers/scsi/Makefile Fri Feb 7 21:52:42 2003
+++ b/drivers/scsi/Makefile Fri Feb 7 21:52:42 2003
@@ -45,7 +45,7 @@
obj-$(CONFIG_SUN3_SCSI) += sun3_scsi.o sun3_scsi_vme.o
obj-$(CONFIG_MVME16x_SCSI) += mvme16x.o 53c7xx.o
obj-$(CONFIG_BVME6000_SCSI) += bvme6000.o 53c7xx.o
-obj-$(CONFIG_SCSI_SIM710) += sim710.o
+obj-$(CONFIG_SCSI_SIM710) += sim710.o 53c700.o
obj-$(CONFIG_SCSI_ADVANSYS) += advansys.o
obj-$(CONFIG_SCSI_PCI2000) += pci2000.o
obj-$(CONFIG_SCSI_PCI2220I) += pci2220i.o
diff -Nru a/drivers/scsi/sim710.c b/drivers/scsi/sim710.c
--- a/drivers/scsi/sim710.c Fri Feb 7 21:52:42 2003
+++ b/drivers/scsi/sim710.c Fri Feb 7 21:52:42 2003
@@ -22,96 +22,41 @@
* Some multiboard fixes from Rolf Eike Beer.
* Auto probing of EISA config space from Trevor Hemsley.
*
- * Various bits of code in this driver have been copied from 53c7,8xx,c,
- * which is coyright Drew Eckhardt. The scripts for the SCSI chip are
- * compiled with the script compiler written by Drew.
- *
- * This is a simple driver for the NCR53c710. More complex drivers
- * for this chip (e.g. 53c7xx.c) require that the scsi chip be able to
- * do DMA block moves between memory and on-chip registers, which can
- * be a problem if those registers are in the I/O address space. There
- * can also be problems on hardware where the registers are memory
- * mapped, if the design is such that memory-to-memory transfers initiated
- * by the scsi chip cannot access the chip registers.
- *
- * This driver is designed to avoid these problems and is intended to
- * work with any Intel machines using 53c710 chips, including various
- * Compaq and NCR machines. It was initially written for the Tadpole
- * TP34V VME board which is 68030 based.
- *
- * The driver supports boot-time parameters similar to
- * sim710=addr:0x9000,irq:15
- * and insmod parameters similar to
- * sim710="addr:0x9000 irq:15"
- *
- * Multiple controllers can also be set up by command line, provided the
- * addr: parameter is specified first for each controller. e.g.
- * sim710="addr:0x9000 irq:15 addr:0x8000 irq:14"
- *
- * To seperate the different options, ' ', '+', and ',' can be used, except
- * that ',' can not be used in module parameters. ' ' can be a pain, because
- * it needs to be quoted, which causes problems with some installers.
- * The command line above is completely equivalent to
- * sim710="addr:0x9000+irq:15+addr:0x8000+irq:14"
- *
- * The complete list of options are:
- *
- * addr:0x9000 Specifies the base I/O port (or address) of the 53C710.
- * irq:15 Specifies the IRQ number used by the 53c710.
- * debug:0xffff Generates lots of debug output.
- * ignore:0x0a Makes the driver ignore SCSI IDs 0 and 2.
- * nodisc:0x70 Prevents disconnects from IDs 6, 5 and 4.
- * noneg:0x10 Prevents SDTR negotiation on ID 4.
- * disabled:1 Completely disables the driver. When present, overrides
- * all other options.
- *
- * The driver will auto-probe chip addresses and IRQs now, so typically no
- * parameters are needed. Auto-probing of addresses is disabled if any addr:
- * parameters are specified.
- *
- * Current limitations:
- *
- * o Async only
- * o Severely lacking in error recovery
- * o 'debug:' should be per host really.
+ * Rewritten to use 53c700.c by James.Bottomley@SteelEye.com
*
*/
#include <linux/config.h>
#include <linux/module.h>
-#include <linux/version.h>
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/string.h>
-#include <linux/ioport.h>
-#include <linux/delay.h>
-#include <linux/sched.h>
-#include <linux/proc_fs.h>
+#include <linux/blk.h>
+#include <linux/device.h>
#include <linux/init.h>
+#ifdef CONFIG_MCA
#include <linux/mca.h>
-#include <linux/interrupt.h>
-#include <asm/dma.h>
-#include <asm/system.h>
-#include <linux/spinlock.h>
-#include <asm/io.h>
-#include <asm/pgtable.h>
-#include <asm/byteorder.h>
-#include <linux/blk.h>
+#endif
+#ifdef CONFIG_EISA
+#include <linux/eisa.h>
+#endif
-/* All targets are I/O mapped at the moment */
-#define IO_MAPPED
+#include "scsi.h"
+#include "hosts.h"
+#include "53c700.h"
-#if defined(CONFIG_MCA)
+/* Must be enough for both EISA and MCA */
+#define MAX_SLOTS 8
+static __u8 __initdata id_array[MAX_SLOTS] = { [0 ... MAX_SLOTS-1] = 7 };
+
+/* info is used to communicate global data across the driver register
+ * because the struct device_driver doesn't have any info fields. Sigh */
+struct sim710_info {
+ Scsi_Host_Template *tpnt;
+ int found;
+};
-/*
- * For each known microchannel card using the 53c710 we need a list
- * of possible IRQ and IO settings, as well as their corresponding
- * bit assignment in pos[]. This might get cumbersome if there
- * are more than a few cards (I only know of 2 at this point).
- */
+static __initdata struct sim710_info sim710_global_info;
-#define MCA_53C710_IDS { 0x01bb, 0x01ba, 0x004f }
+#if defined(CONFIG_MCA)
/* CARD ID 01BB and 01BA use the same pos values */
@@ -130,63 +75,6 @@
#endif
-#include "scsi.h"
-#include "hosts.h"
-#include "sim710.h"
-
-#include<linux/stat.h>
-
-#define DEBUG
-#undef DEBUG_LIMIT_INTS /* Define to 10 to hang driver after 10 ints */
-
-/* Debug options available via the "debug:0x1234" parameter */
-
-#define DEB_NONE 0x0000 /* Nothing */
-#define DEB_HALT 0x0001 /* Detailed trace of chip halt funtion */
-#define DEB_REGS 0x0002 /* All chip register read/writes */
-#define DEB_SYNC 0x0004 /* Sync/async negotiation */
-#define DEB_PMM 0x0008 /* Phase mis-match handling */
-#define DEB_INTS 0x0010 /* General interrupt trace */
-#define DEB_TOUT 0x0020 /* Selection timeouts */
-#define DEB_RESUME 0x0040 /* Resume addresses for the script */
-#define DEB_CMND 0x0080 /* Commands and status returned */
-#define DEB_FIXUP 0x0100 /* Fixup of scsi addresses */
-#define DEB_DISC 0x0200 /* Disconnect/reselect handling */
-
-#define DEB_ANY 0xffff /* Any and all debug options */
-
-#ifdef DEBUG
-#define DEB(m,x) if (sim710_debug & m) x
-int sim710_debug;
-#else
-#define DEB(m,x)
-#endif
-
-/* Redefine scsi_done to force renegotiation of (a)sync transfers
- * following any failed command.
- */
-
-#define SCSI_DONE(cmd) { \
- DEB(DEB_CMND, printk("scsi%d: Complete %08x\n", \
- host->host_no, cmd->result)); \
- if (cmd->result) \
- hostdata->negotiate |= (1 << cmd->target); \
- cmd->scsi_done(cmd); \
- }
-
-#ifndef offsetof
-#define offsetof(t, m) ((size_t) (&((t *)0)->m))
-#endif
-
-#define STATE_INITIALISED 0
-#define STATE_HALTED 1
-#define STATE_IDLE 2
-#define STATE_BUSY 3
-#define STATE_DISABLED 4
-
-#define MAXBOARDS 4 /* Increase this and the sizes of the
- arrays below, if you need more.. */
-
#ifdef MODULE
char *sim710; /* command line passed by insmod */
@@ -199,1583 +87,295 @@
#endif
-static int sim710_errors; /* Count of error interrupts */
-static int sim710_intrs; /* Count of all interrupts */
-static int ignore_ids[MAXBOARDS]; /* Accept all SCSI IDs */
-static int opt_nodisc[MAXBOARDS]; /* Allow disconnect on all IDs */
-static int opt_noneg[MAXBOARDS]; /* Allow SDTR negotiation on all IDs */
-static int hostdata_order; /* Encoded size of hostdata for free_pages() */
-static int no_of_boards; /* Actual number of boards/chips */
-static unsigned int bases[MAXBOARDS]; /* Base addresses of chips */
-static unsigned int irq_vectors[MAXBOARDS]; /* IRQ vectors used by chips */
-
-/* The SCSI Script!!! */
-
-#include "sim710_d.h"
-
-/* Now define offsets in the DSA, as (A_dsa_xxx/4) */
-
-#define DSA_SELECT (A_dsa_select/4)
-#define DSA_MSGOUT (A_dsa_msgout/4)
-#define DSA_CMND (A_dsa_cmnd/4)
-#define DSA_STATUS (A_dsa_status/4)
-#define DSA_MSGIN (A_dsa_msgin/4)
-#define DSA_DATAIN (A_dsa_datain/4)
-#define DSA_DATAOUT (A_dsa_dataout/4)
-#define DSA_SIZE (A_dsa_size/4)
-
-#define MAX_SG 128 /* Scatter/Gather elements */
-
-#define MAX_MSGOUT 8
-#define MAX_MSGIN 8
-#define MAX_CMND 12
-#define MAX_STATUS 1
-
-struct sim710_hostdata{
- int state;
- Scsi_Cmnd * issue_queue;
- Scsi_Cmnd * running;
- int chip;
- u8 negotiate;
- u8 reselected_identify;
- u8 msgin_buf[MAX_MSGIN];
- u8 msg_reject;
- u32 test1_src __attribute__ ((aligned (4)));
- u32 test1_dst;
-
- struct sim710_target {
- Scsi_Cmnd *cur_cmd;
- u32 resume_offset;
- u32 data_in_jump;
- u32 data_out_jump;
- u32 dsa[DSA_SIZE]; /* SCSI Script DSA area */
- u8 dsa_msgout[MAX_MSGOUT];
- u8 dsa_msgin[MAX_MSGIN];
- u8 dsa_cdb[MAX_CMND];
- u8 dsa_status[MAX_STATUS];
- } target[8];
-
- u32 script[sizeof(SCRIPT)/4] __attribute__ ((aligned (4)));
-};
-
-
-/* Template to request asynchronous transfers */
-
-static const unsigned char async_message[] = {
- EXTENDED_MESSAGE, 3 /* length */, EXTENDED_SDTR, 0, 0 /* asynchronous */};
-
-
-static void sim710_intr_handle(int irq, void *dev_id, struct pt_regs *regs);
-static void do_sim710_intr_handle(int irq, void *dev_id, struct pt_regs *regs);
-static __inline__ void run_process_issue_queue(struct sim710_hostdata *);
-static void process_issue_queue (struct sim710_hostdata *, unsigned long flags);
-static int full_reset(struct Scsi_Host * host);
-
-
-/*
- * Function : static void ncr_dump (struct Scsi_Host *host)
- *
- * Purpose : Dump (possibly) useful info
- *
- * Inputs : host - pointer to this host adapter's structure
- */
-
-static void
-ncr_dump (struct Scsi_Host *host)
-{
- unsigned long flags;
- struct sim710_hostdata *hostdata = (struct sim710_hostdata *)
- host->hostdata[0];
-
- save_flags(flags);
- cli();
- printk("scsi%d: Chip register contents:\n", host->host_no);
- printk(" (script at virt %p, bus %lx)\n",
- hostdata->script, virt_to_bus(hostdata->script));
- printk(" 00 sien: %02x sdid: %02x scntl1:%02x scntl0:%02x\n"
- " 04 socl: %02x sodl: %02x sxfer: %02x scid: %02x\n"
- " 08 sbcl: %02x sbdl: %02x sidl: %02x sfbr: %02x\n"
- " 0C sstat2:%02x sstat1:%02x sstat0:%02x dstat: %02x\n"
- " 10 dsa: %08x\n"
- " 14 ctest3:%02x ctest2:%02x ctest1:%02x ctest0:%02x\n"
- " 18 ctest7:%02x ctest6:%02x ctest5:%02x ctest4:%02x\n"
- " 1C temp: %08x\n"
- " 20 lcrc: %02x ctest8:%02x istat: %02x dfifo: %02x\n"
- " 24 dbc: %08x dnad: %08x dsp: %08x\n"
- " 30 dsps: %08x scratch:%08x\n"
- " 38 dcntl: %02x dwt: %02x dien: %02x dmode: %02x\n"
- " 3C adder: %08x\n",
- NCR_read8(SIEN_REG), NCR_read8(SDID_REG), NCR_read8(SCNTL1_REG),
- NCR_read8(SCNTL0_REG), NCR_read8(SOCL_REG), NCR_read8(SODL_REG),
- NCR_read8(SXFER_REG), NCR_read8(SCID_REG), NCR_read8(SBCL_REG),
- NCR_read8(SBDL_REG), NCR_read8(SIDL_REG), NCR_read8(SFBR_REG),
- NCR_read8(SSTAT2_REG), NCR_read8(SSTAT1_REG), NCR_read8(SSTAT0_REG),
- NCR_read8(DSTAT_REG), NCR_read32(DSA_REG), NCR_read8(CTEST3_REG),
- NCR_read8(CTEST2_REG), NCR_read8(CTEST1_REG), NCR_read8(CTEST0_REG),
- NCR_read8(CTEST7_REG), NCR_read8(CTEST6_REG), NCR_read8(CTEST5_REG),
- NCR_read8(CTEST4_REG), NCR_read8(TEMP_REG), NCR_read8(LCRC_REG),
- NCR_read8(CTEST8_REG), NCR_read8(ISTAT_REG), NCR_read8(DFIFO_REG),
- NCR_read32(DBC_REG), NCR_read32(DNAD_REG), NCR_read32(DSP_REG),
- NCR_read32(DSPS_REG), NCR_read32(SCRATCH_REG), NCR_read8(DCNTL_REG),
- NCR_read8(DWT_REG), NCR_read8(DIEN_REG), NCR_read8(DMODE_REG),
- NCR_read32(ADDER_REG));
-
- restore_flags(flags);
-}
-
-
-/*
- * Function: int param_setup(char *str)
- */
+#ifdef MODULE
+#define ARG_SEP ' '
+#else
+#define ARG_SEP ','
+#endif
__init int
param_setup(char *str)
{
- char *cur = str;
- char *p, *pc, *pv;
- int val;
- int c;
-
- no_of_boards = 0;
- while (no_of_boards < MAXBOARDS && cur != NULL &&
- (pc = strchr(cur, ':')) != NULL) {
- char *pe;
-
- val = 0;
- pv = pc;
- c = *++pv;
+ char *pos = str, *next;
+ int slot = -1;
- val = (int) simple_strtoul(pv, &pe, 0);
+ while(pos != NULL && (next = strchr(pos, ':')) != NULL) {
+ int val = (int)simple_strtoul(++next, NULL, 0);
- if (!strncmp(cur, "addr:", 5)) {
- bases[no_of_boards++] = val;
- }
-#ifdef DEBUG
- else if (!strncmp(cur, "debug:", 6)) {
- sim710_debug = val;
- }
-#endif
- else if (no_of_boards == 0) {
- printk("sim710: Invalid parameters, addr: must come first\n");
- no_of_boards = -1;
- return 1;
- }
- else if (!strncmp(cur, "irq:", 4))
- irq_vectors[no_of_boards-1] = val;
- else if (!strncmp(cur, "ignore:", 7))
- ignore_ids[no_of_boards-1] = val;
- else if (!strncmp(cur, "nodisc:", 7))
- opt_nodisc[no_of_boards-1] = val;
- else if (!strncmp(cur, "noneg:", 6))
- opt_noneg[no_of_boards-1] = val;
- else if (!strncmp(cur, "disabled:", 9)) {
- no_of_boards = -1;
- return 1;
- }
- else {
- printk("sim710: unexpected boot option '%.*s'\n", (int)(pc-cur+1), cur);
- no_of_boards = -1;
- return 1;
+ if(!strncmp(pos, "slot:", 5))
+ slot = val;
+ else if(!strncmp(pos, "id:", 3)) {
+ if(slot == -1) {
+ printk(KERN_WARNING "sim710: Must specify slot for id parameter\n");
+ } else if(slot > MAX_SLOTS) {
+ printk(KERN_WARNING "sim710: Illegal slot %d for id %d\n", slot, val);
+ } else {
+ id_array[slot] = val;
+ }
+ }
+ if((pos = strchr(pos, ARG_SEP)) != NULL)
+ pos++;
}
-
- /* Allow ',', ' ', or '+' seperators. Used to be ',' at boot and
- * ' ' for module load, some installers crap out on the space and
- * insmod doesn't like the comma.
- */
- if ((p = strchr(cur, ',')) || (p = strchr(cur, ' ')) ||
- (p = strchr(cur, '+')))
- cur = p + 1;
- else
- break;
- }
- return 1;
+ return 1;
}
#ifndef MODULE
__setup("sim710=", param_setup);
#endif
-
-/*
- * Function: static const char *sbcl_to_phase (int sbcl)
- */
-
-static const char *
-sbcl_to_phase (int sbcl) {
- switch (sbcl & SBCL_PHASE_MASK) {
- case SBCL_PHASE_DATAIN:
- return "DATAIN";
- case SBCL_PHASE_DATAOUT:
- return "DATAOUT";
- case SBCL_PHASE_MSGIN:
- return "MSGIN";
- case SBCL_PHASE_MSGOUT:
- return "MSGOUT";
- case SBCL_PHASE_CMDOUT:
- return "CMDOUT";
- case SBCL_PHASE_STATIN:
- return "STATUSIN";
- default:
- return "unknown";
- }
-}
-
-
-/*
- * Function : static int ncr_halt (struct Scsi_Host *host)
- *
- * Purpose : halts the SCSI SCRIPTS(tm) processor on the NCR chip
- *
- * Inputs : host - SCSI chip to halt
- *
- * Returns : 0 on success
- */
-
-static int
-ncr_halt (struct Scsi_Host *host)
-{
- unsigned long flags;
- unsigned char istat, tmp;
- struct sim710_hostdata *hostdata = (struct sim710_hostdata *)
- host->hostdata[0];
- int stage;
- int timeout;
- int res = 0;
-
- save_flags(flags);
- cli();
- /* Stage 0 : eat all interrupts
- Stage 1 : set ABORT
- Stage 2 : eat all but abort interrupts
- Stage 3 : eat all interrupts
- We loop for 50000 times with a delay of 10us which should give us
- about half a second.
- */
- for (stage = 0, timeout = 50000; timeout; timeout--) {
- if (stage == 1) {
- DEB(DEB_HALT, printk("ncr_halt: writing ISTAT_ABRT\n"));
- NCR_write8(ISTAT_REG, ISTAT_ABRT);
- ++stage;
- }
- istat = NCR_read8 (ISTAT_REG);
- if (istat & ISTAT_SIP) {
- DEB(DEB_HALT, printk("ncr_halt: got ISTAT_SIP, istat=%02x\n", istat));
- tmp = NCR_read8(SSTAT0_REG);
- DEB(DEB_HALT, printk("ncr_halt: got SSTAT0_REG=%02x\n", tmp));
- } else if (istat & ISTAT_DIP) {
- DEB(DEB_HALT, printk("ncr_halt: got ISTAT_DIP, istat=%02x\n", istat));
- tmp = NCR_read8(DSTAT_REG);
- DEB(DEB_HALT, printk("ncr_halt: got DSTAT_REG=%02x\n", tmp));
- if (stage == 2) {
- if (tmp & DSTAT_ABRT) {
- DEB(DEB_HALT, printk("ncr_halt: got DSTAT_ABRT, clearing istat\n"));
- NCR_write8(ISTAT_REG, 0);
- ++stage;
- } else {
- res = 1;
- break;
- }
- }
- }
- if (!(istat & (ISTAT_SIP|ISTAT_DIP))) {
- if (stage == 0)
- ++stage;
- else if (stage == 3)
- break;
- }
- udelay(10);
- }
- restore_flags(flags);
-
- if (timeout == 0 || res) {
- printk(KERN_ALERT "scsi%d: could not halt NCR chip\n", host->host_no);
- return 1;
- }
- else {
- hostdata->state = STATE_HALTED;
- return 0;
- }
-}
-
-/*
- * Function : static void sim710_soft_reset (struct Scsi_Host *host)
- *
- * Purpose : perform a soft reset of the NCR53c7xx chip
- *
- * Inputs : host - pointer to this host adapter's structure
- *
- * Preconditions : sim710_init must have been called for this
- * host.
- *
- */
-
-static void
-sim710_soft_reset (struct Scsi_Host *host)
-{
- unsigned long flags;
-
- save_flags(flags);
- cli();
- /*
- * Do a soft reset of the chip so that everything is
- * reinitialized to the power-on state.
- *
- * Basically follow the procedure outlined in the NCR53c700
- * data manual under Chapter Six, How to Use, Steps Necessary to
- * Start SCRIPTS, with the exception of actually starting the
- * script and setting up the synchronous transfer gunk.
- */
-
- /* XXX Should we reset the scsi bus here? */
-
- NCR_write8(SCNTL1_REG, SCNTL1_RST); /* Reset the bus */
- udelay(50);
- NCR_write8(SCNTL1_REG, 0);
-
- udelay(500);
-
- NCR_write8(ISTAT_REG, ISTAT_10_SRST); /* Reset the chip */
- udelay(50);
- NCR_write8(ISTAT_REG, 0);
-
- mdelay(1000); /* Let devices recover */
-
- NCR_write32(SCRATCH_REG, 0);
- NCR_write8(DCNTL_REG, DCNTL_10_COM | DCNTL_700_CF_3);
- NCR_write8(CTEST7_REG, CTEST7_10_CDIS|CTEST7_STD);
- NCR_write8(DMODE_REG, DMODE_10_BL_8 | DMODE_10_FC2);
- NCR_write8(SCID_REG, 1 << host->this_id);
- NCR_write8(SBCL_REG, 0);
- NCR_write8(SXFER_REG, 0);
- NCR_write8(SCNTL1_REG, SCNTL1_ESR_700);
- NCR_write8(SCNTL0_REG, SCNTL0_EPC | SCNTL0_EPG_700 | SCNTL0_ARB1 |
- SCNTL0_ARB2);
-
- NCR_write8(DIEN_REG, DIEN_700_BF |
- DIEN_ABRT | DIEN_SSI | DIEN_SIR | DIEN_700_OPC);
-
- NCR_write8(SIEN_REG_700,
- SIEN_PAR | SIEN_700_STO | SIEN_RST | SIEN_UDC | SIEN_SGE | SIEN_MA);
-
- restore_flags(flags);
-}
-
-
-/*
- * Function : static void sim710_driver_init (struct Scsi_Host *host)
- *
- * Purpose : Initialize internal structures, as required on startup, or
- * after a SCSI bus reset.
- *
- * Inputs : host - pointer to this host adapter's structure
- */
-
-static void
-sim710_driver_init (struct Scsi_Host *host)
-{
- struct sim710_hostdata *hostdata = (struct sim710_hostdata *)
- host->hostdata[0];
- int i;
-
- hostdata->running = NULL;
- memcpy (hostdata->script, SCRIPT, sizeof(SCRIPT));
- for (i = 0; i < PATCHES; i++)
- hostdata->script[LABELPATCHES[i]] += isa_virt_to_bus(hostdata->script);
- patch_abs_32 (hostdata->script, 0, reselected_identify,
- isa_virt_to_bus((void *)&(hostdata->reselected_identify)));
- patch_abs_32 (hostdata->script, 0, msgin_buf,
- isa_virt_to_bus((void *)&(hostdata->msgin_buf[0])));
- patch_abs_32 (hostdata->script, 0, msg_reject,
- isa_virt_to_bus((void *)&(hostdata->msg_reject)));
- patch_abs_32 (hostdata->script, 0, test1_src,
- isa_virt_to_bus((void *)&(hostdata->test1_src)));
- patch_abs_32 (hostdata->script, 0, test1_dst,
- isa_virt_to_bus((void *)&(hostdata->test1_dst)));
- hostdata->state = STATE_INITIALISED;
- hostdata->negotiate = 0xff;
-}
-
-
-/* Handle incoming Synchronous data transfer request. If our negotiate
- * flag is set then this is a response to our request, otherwise it is
- * spurious request from the target. Don't really expect target initiated
- * SDTRs, because we always negotiate on the first command. Could still
- * get them though..
- * The chip is currently paused with ACK asserted on the last byte of the
- * SDTR.
- * resa is the resume address if the message is in response to our outgoing
- * SDTR. Only possible on initial identify.
- * resb is the resume address if the message exchange is initiated by the
- * target.
- */
-
-static u32
-handle_sdtr (struct Scsi_Host * host, Scsi_Cmnd * cmd, u32 resa, u32 resb)
-{
- struct sim710_hostdata *hostdata = (struct sim710_hostdata *)host->hostdata[0];
- struct sim710_target *targdata = hostdata->target + cmd->target;
- u32 resume_offset;
-
- if (resa && hostdata->negotiate & (1 << cmd->target)) {
- DEB(DEB_SYNC, printk("scsi%d: Response to host SDTR = %02x %02x\n",
- host->host_no, hostdata->msgin_buf[3], hostdata->msgin_buf[4]));
- /* We always issue an SDTR with the identify, so we must issue
- * the CDB next.
- */
- resume_offset = resa;
- hostdata->negotiate &= ~(1 << cmd->target);
- }
- else {
- DEB(DEB_SYNC, printk("scsi%d: Target initiated SDTR = %02x %02x\n",
- host->host_no, hostdata->msgin_buf[3], hostdata->msgin_buf[4]));
- memcpy(targdata->dsa_msgout, async_message, sizeof(async_message));
- targdata->dsa[DSA_MSGOUT] = sizeof(async_message);
- /* I guess the target could do this anytime; we have to send our
- * response, and then continue (sending the CDB if not already done).
- */
- resume_offset = resb;
- }
- return resume_offset;
-}
-
-
-/*
- * Function : static int datapath_residual (Scsi_Host *host)
- *
- * Purpose : return residual data count of what's in the chip.
- *
- * Inputs : host - SCSI host
- */
-
-static int
-datapath_residual (struct Scsi_Host *host) {
- int count, synchronous, sstat;
- unsigned int ddir;
-
- count = ((NCR_read8 (DFIFO_REG) & DFIFO_10_BO_MASK) -
- (NCR_read32 (DBC_REG) & DFIFO_10_BO_MASK)) & DFIFO_10_BO_MASK;
- synchronous = NCR_read8 (SXFER_REG) & SXFER_MO_MASK;
- ddir = NCR_read8 (CTEST0_REG_700) & CTEST0_700_DDIR;
-
- if (ddir) {
- /* Receive */
- if (synchronous)
- count += (NCR_read8 (SSTAT2_REG) & SSTAT2_FF_MASK) >> SSTAT2_FF_SHIFT;
- else
- if (NCR_read8 (SSTAT1_REG) & SSTAT1_ILF)
- ++count;
- } else {
- /* Send */
- sstat = NCR_read8 (SSTAT1_REG);
- if (sstat & SSTAT1_OLF)
- ++count;
- if (synchronous && (sstat & SSTAT1_ORF))
- ++count;
- }
- return count;
-}
-
-
-static u32
-handle_idd (struct Scsi_Host * host, Scsi_Cmnd * cmd)
+__init int
+sim710_probe_common(struct device *dev, unsigned long base_addr,
+ int irq, int clock, int differential, int scsi_id)
{
- struct sim710_hostdata *hostdata =
- (struct sim710_hostdata *)host->hostdata[0];
- struct sim710_target *targdata = hostdata->target + cmd->target;
- u32 resume_offset = 0, index;
-
- index = (u32)((u32 *)(isa_bus_to_virt(NCR_read32(DSP_REG))) - hostdata->script);
-
- switch (index) {
- case Ent_wait_disc_complete/4 + 2:
- cmd->result = targdata->dsa_status[0];
- SCSI_DONE(cmd);
- targdata->cur_cmd = NULL;
- resume_offset = Ent_reselect;
- break;
- case Ent_wait_disc2/4 + 2:
- /* Disconnect after command - just wait for a reselect */
- targdata->resume_offset = Ent_resume_msgin2a;
- resume_offset = Ent_reselect;
- break;
- case Ent_wait_disc3/4 + 2:
- /* Disconnect after the data phase */
- targdata->resume_offset = Ent_resume_msgin3a;
- resume_offset = Ent_reselect;
- break;
- case Ent_wait_disc1/4 + 2:
- /* Disconnect before command - not expected */
- targdata->resume_offset = Ent_resume_msgin1a;
- resume_offset = Ent_reselect;
- break;
- default:
- printk("scsi%d: Unexpected Illegal Instruction, script[%04x]\n",
- host->host_no, index);
- sim710_errors++;
- /* resume_offset is zero, which will cause host reset */
- }
- return resume_offset;
-}
+ struct Scsi_Host * host = NULL;
+ struct NCR_700_Host_Parameters *hostdata =
+ kmalloc(sizeof(struct NCR_700_Host_Parameters), GFP_KERNEL);
+ printk(KERN_NOTICE "sim710: %s\n", dev->name);
+ printk(KERN_NOTICE "sim710: irq = %d, clock = %d, base = 0x%lx, scsi_id = %d\n",
+ irq, clock, base_addr, scsi_id);
-/* Handle a phase mismatch.
- */
-
-static u32
-handle_phase_mismatch (struct Scsi_Host * host, Scsi_Cmnd * cmd)
-{
- struct sim710_hostdata *hostdata =
- (struct sim710_hostdata *)host->hostdata[0];
- struct sim710_target *targdata = hostdata->target + cmd->target;
- u32 resume_offset = 0, index;
- unsigned char sbcl;
-
- sbcl = NCR_read8(SBCL_REG) & SBCL_PHASE_MASK;
- index = (u32)((u32 *)(isa_bus_to_virt(NCR_read32(DSP_REG))) - hostdata->script);
-
- DEB(DEB_PMM, printk("scsi%d: Phase mismatch, phase %s (%x) at script[0x%x]\n",
- host->host_no, sbcl_to_phase(sbcl), sbcl, index));
- DEB(DEB_PMM, print_command(cmd->cmnd));
-
- if (index == Ent_done_ident/4) {
- /* Sending initial message out - probably rejecting our sync
- * negotiation request.
- */
- NCR_write8(SOCL_REG, 0); /* Negate ATN */
- if (sbcl == SBCL_PHASE_MSGIN)
- resume_offset = Ent_resume_rej_ident;
- else if (sbcl == SBCL_PHASE_CMDOUT) {
- /* Some old devices (SQ555) switch to cmdout after the first
- * byte of an identify message, regardless of whether we
- * have more bytes to send!
- */
- printk("scsi%d: Unexpected switch to CMDOUT during IDENTIFY\n",
- host->host_no);
- resume_offset = Ent_resume_cmd;
+ if(hostdata == NULL) {
+ printk(KERN_ERR "sim710: Failed to allocate host data\n");
+ goto out;
}
- else if (sbcl == SBCL_PHASE_STATIN) {
- /* Some devices do this on parity error, at least */
- printk("scsi%d: Unexpected switch to STATUSIN on initial message out\n",
- host->host_no);
- resume_offset = Ent_end_data_trans;
- }
- else {
- printk("scsi%d: Unexpected phase change to %s on initial msgout\n",
- host->host_no, sbcl_to_phase(sbcl));
- /* resume_offset is zero, which will cause a host reset */
- }
- hostdata->negotiate &= ~(1 << cmd->target);
- }
- else if (index > Ent_patch_input_data/4 &&
- index < Ent_patch_output_data/4) {
- /* DataIn transfer phase */
- u32 sg_id, oaddr, olen, naddr, nlen;
- int residual;
-
- sg_id = (index - Ent_patch_input_data/4 - 4) / 2;
- targdata->data_in_jump = hostdata->script[Ent_patch_input_data/4+1] =
- isa_virt_to_bus(hostdata->script + Ent_patch_input_data/4 + sg_id * 2 + 2);
- olen = targdata->dsa[DSA_DATAIN + sg_id * 2];
- oaddr = targdata->dsa[DSA_DATAIN + sg_id * 2 + 1];
- residual = datapath_residual (host);
- if (residual)
- printk("scsi%d: Residual count %d on DataIn - NOT expected!!!",
- host->host_no, residual);
- naddr = NCR_read32(DNAD_REG) - residual;
- nlen = (NCR_read32(DBC_REG) & 0x00ffffff) + residual;
- DEB(DEB_PMM, printk("scsi%d: DIN sg %d, old %08x/%08x, new %08x/%08x (%d)\n",
- host->host_no, sg_id, oaddr, olen, naddr, nlen, residual));
- if (oaddr+olen != naddr+nlen) {
- printk("scsi%d: PMM DIN counts error: 0x%x + 0x%x != 0x%x + 0x%x",
- host->host_no, oaddr, olen, naddr, nlen);
- }
- else {
- targdata->dsa[DSA_DATAIN + sg_id * 2] = nlen;
- targdata->dsa[DSA_DATAIN + sg_id * 2 + 1] = naddr;
- resume_offset = Ent_resume_pmm;
- }
- }
- else if (index > Ent_patch_output_data/4 &&
- index <= Ent_end_data_trans/4) {
- /* Dataout transfer phase */
- u32 sg_id, oaddr, olen, naddr, nlen;
- int residual;
-
- sg_id = (index - Ent_patch_output_data/4 - 4) / 2;
- targdata->data_out_jump = hostdata->script[Ent_patch_output_data/4+1] =
- isa_virt_to_bus(hostdata->script + Ent_patch_output_data/4 + sg_id * 2 + 2);
- olen = targdata->dsa[DSA_DATAOUT + sg_id * 2];
- oaddr = targdata->dsa[DSA_DATAOUT + sg_id * 2 + 1];
- residual = datapath_residual (host);
- naddr = NCR_read32(DNAD_REG) - residual;
- nlen = (NCR_read32(DBC_REG) & 0x00ffffff) + residual;
- DEB(DEB_PMM, printk("scsi%d: DOUT sg %d, old %08x/%08x, new %08x/%08x (%d)\n",
- host->host_no, sg_id, oaddr, olen, naddr, nlen, residual));
- if (oaddr+olen != naddr+nlen) {
- printk("scsi%d: PMM DOUT counts error: 0x%x + 0x%x != 0x%x + 0x%x",
- host->host_no, oaddr, olen, naddr, nlen);
- }
- else {
- targdata->dsa[DSA_DATAOUT + sg_id * 2] = nlen;
- targdata->dsa[DSA_DATAOUT + sg_id * 2 + 1] = naddr;
- resume_offset = Ent_resume_pmm;
- }
- }
- else if (sbcl == SBCL_PHASE_STATIN) {
- /* Change to Status In at some random point; probably wants to report a
- * parity error or similar.
- */
- printk("scsi%d: Unexpected phase change to STATUSIN at index 0x%x\n",
- host->host_no, index);
- resume_offset = Ent_end_data_trans;
- }
- else {
- printk("scsi%d: Unexpected phase change to %s at index 0x%x\n",
- host->host_no, sbcl_to_phase(sbcl), index);
- /* resume_offset is zero, which will cause a host reset */
- }
- /* Flush DMA FIFO */
- NCR_write8 (CTEST8_REG, CTEST8_10_CLF);
- while (NCR_read8 (CTEST8_REG) & CTEST8_10_CLF);
-
- return resume_offset;
-}
-
-
-static u32
-handle_script_int(struct Scsi_Host * host, Scsi_Cmnd * cmd)
-{
- struct sim710_hostdata *hostdata =
- (struct sim710_hostdata *)host->hostdata[0];
- struct sim710_target *targdata = hostdata->target + cmd->target;
- u32 dsps, resume_offset = 0;
- unsigned char sbcl;
-
- dsps = NCR_read32(DSPS_REG);
-
- switch (dsps) {
- case A_int_cmd_complete:
- cmd->result = targdata->dsa_status[0];
- SCSI_DONE(cmd);
- targdata->cur_cmd = NULL;
- resume_offset = Ent_reselect;
- break;
- case A_int_msg_sdtr1:
- resume_offset = handle_sdtr(host, cmd,
- Ent_resume_msgin1a, Ent_resume_msgin1b);
- break;
- case A_int_msg_sdtr2:
- resume_offset = handle_sdtr(host, cmd, 0, Ent_resume_msgin2b);
- break;
- case A_int_msg_sdtr3:
- resume_offset = handle_sdtr(host, cmd, 0, Ent_resume_msgin3b);
- break;
- case A_int_disc1:
- /* Disconnect before command - not expected */
- targdata->resume_offset = Ent_resume_msgin1a;
- resume_offset = Ent_reselect;
- break;
- case A_int_disc2:
- /* Disconnect after command - just wait for a reselect */
- targdata->resume_offset = Ent_resume_msgin2a;
- resume_offset = Ent_reselect;
- break;
- case A_int_disc3:
- /* Disconnect after the data phase */
- targdata->resume_offset = Ent_resume_msgin3a;
- resume_offset = Ent_reselect;
- break;
- case A_int_reselected:
- hostdata->script[Ent_patch_output_data/4+1] = targdata->data_out_jump;
- hostdata->script[Ent_patch_input_data/4+1] = targdata->data_in_jump;
- NCR_write32(DSA_REG, isa_virt_to_bus(targdata->dsa));
- resume_offset = targdata->resume_offset;
- break;
- case A_int_data_bad_phase:
- sbcl = NCR_read8(SBCL_REG) & SBCL_PHASE_MASK;
- printk("scsi%d: int_data_bad_phase, phase %s (%x)\n",
- host->host_no, sbcl_to_phase(sbcl), sbcl);
- break;
- case A_int_bad_msg1:
- case A_int_bad_msg2:
- case A_int_bad_msg3:
- case A_int_cmd_bad_phase:
- case A_int_no_msgout1:
- case A_int_no_msgout2:
- case A_int_no_msgout3:
- case A_int_not_cmd_complete:
- case A_int_sel_no_ident:
- case A_int_sel_not_cmd:
- case A_int_status_not_msgin:
- case A_int_resel_not_msgin:
- case A_int_selected:
- case A_int_not_rej:
- default:
- sbcl = NCR_read8(SBCL_REG) & SBCL_PHASE_MASK;
- printk("scsi%d: Unimplemented script interrupt: %08x, phase %s\n",
- host->host_no, dsps, sbcl_to_phase(sbcl));
- sim710_errors++;
- /* resume_offset is zero, which will cause a host reset */
- }
- return resume_offset;
-}
-
-
-/* A quick wrapper for sim710_intr_handle to grab the spin lock */
-
-static void
-do_sim710_intr_handle(int irq, void *dev_id, struct pt_regs *regs)
-{
- struct Scsi_Host *host = dev_id;
- unsigned long flags;
+ memset(hostdata, 0, sizeof(struct NCR_700_Host_Parameters));
- spin_lock_irqsave(host->host_lock, flags);
- sim710_intr_handle(irq, host, regs);
- spin_unlock_irqrestore(host->host_lock, flags);
-}
-
-
-/* A "high" level interrupt handler */
-
-static void
-sim710_intr_handle(int irq, void *dev_id, struct pt_regs *regs)
-{
- struct Scsi_Host * host = (struct Scsi_Host *)dev_id;
- struct sim710_hostdata *hostdata = (struct sim710_hostdata *)host->hostdata[0];
- Scsi_Cmnd * cmd;
- unsigned char istat, dstat;
- unsigned char sstat0;
- u32 scratch, dsps, resume_offset = 0;
-
- istat = NCR_read8(ISTAT_REG);
- if (!(istat & (ISTAT_SIP|ISTAT_DIP)))
- return;
- else {
- sim710_intrs++;
- dsps = NCR_read32(DSPS_REG);
- hostdata->state = STATE_HALTED;
- sstat0 = dstat = 0;
- scratch = NCR_read32(SCRATCH_REG);
- if (istat & ISTAT_SIP) {
- sstat0 = NCR_read8(SSTAT0_REG);
- }
- if (istat & ISTAT_DIP) {
- udelay(10); /* Some comment somewhere about 10cycles
- * between accesses to sstat0 and dstat ??? */
- dstat = NCR_read8(DSTAT_REG);
- }
- DEB(DEB_INTS, printk("scsi%d: Int %d, istat %02x, sstat0 %02x "
- "dstat %02x, dsp [%04x], scratch %02x\n",
- host->host_no, sim710_intrs, istat, sstat0, dstat,
- (u32 *)(isa_bus_to_virt(NCR_read32(DSP_REG))) - hostdata->script,
- scratch));
- if (scratch & 0x100) {
- u8 *p = hostdata->msgin_buf;
-
- DEB(DEB_INTS, printk(" msgin_buf: %02x %02x %02x %02x\n",
- p[0], p[1], p[2], p[3]));
- }
- if ((dstat & DSTAT_SIR) && dsps == A_int_reselected) {
- /* Reselected. Identify the target from LCRC_REG, and
- * update current command. If we were trying to select
- * a device, then that command needs to go back on the
- * issue_queue for later.
- */
- unsigned char lcrc = NCR_read8(LCRC_REG_10);
- int id = 0;
-
- if (!(lcrc & 0x7f)) {
- printk("scsi%d: Reselected with LCRC = %02x\n",
- host->host_no, lcrc);
- cmd = NULL;
- }
- else {
- while (!(lcrc & 1)) {
- id++;
- lcrc >>= 1;
- }
- DEB(DEB_DISC, printk("scsi%d: Reselected by ID %d\n",
- host->host_no, id));
- if (hostdata->running) {
- /* Clear SIGP */
- (void)NCR_read8(CTEST2_REG_700);
-
- DEB(DEB_DISC, printk("scsi%d: Select of %d interrupted "
- "by reselect from %d (%p)\n",
- host->host_no, hostdata->running->target,
- id, hostdata->target[id].cur_cmd));
- cmd = hostdata->running;
- hostdata->target[cmd->target].cur_cmd = NULL;
- cmd->SCp.ptr = (unsigned char *) hostdata->issue_queue;
- hostdata->issue_queue = cmd;
- }
- cmd = hostdata->running = hostdata->target[id].cur_cmd;
- }
+ if(request_region(base_addr, 64, "sim710") == NULL) {
+ printk(KERN_ERR "sim710: Failed to reserve IO region 0x%lx\n",
+ base_addr);
+ goto out_free;
}
- else
- cmd = hostdata->running;
- if (!cmd) {
- printk("scsi%d: No active command!\n", host->host_no);
- printk("scsi%d: Int %d, istat %02x, sstat0 %02x "
- "dstat %02x, dsp [%04x], scratch %02x, dsps %08x\n",
- host->host_no, sim710_intrs, istat, sstat0, dstat,
- (u32 *)(isa_bus_to_virt(NCR_read32(DSP_REG))) - hostdata->script,
- NCR_read32(SCRATCH_REG), dsps);
- /* resume_offset is zero, which will cause a host reset */
- }
- else if (sstat0 & SSTAT0_700_STO) {
- DEB(DEB_TOUT, printk("scsi%d: Selection timeout\n", host->host_no));
- cmd->result = DID_NO_CONNECT << 16;
- SCSI_DONE(cmd);
- hostdata->target[cmd->target].cur_cmd = NULL;
- resume_offset = Ent_reselect;
- }
- else if (sstat0 & (SSTAT0_SGE|SSTAT0_UDC|SSTAT0_RST|SSTAT0_PAR)) {
- printk("scsi%d: Serious error, sstat0 = %02x\n", host->host_no,
- sstat0);
- sim710_errors++;
- /* resume_offset is zero, which will cause a host reset */
- }
- else if (dstat & (DSTAT_BF|DSTAT_ABRT|DSTAT_SSI|DSTAT_WTD)) {
- printk("scsi%d: Serious error, dstat = %02x\n", host->host_no,
- dstat);
- sim710_errors++;
- /* resume_offset is zero, which will cause a host reset */
- }
- else if (dstat & DSTAT_SIR)
- resume_offset = handle_script_int(host, cmd);
- else if (sstat0 & SSTAT0_MA)
- resume_offset = handle_phase_mismatch(host, cmd);
- else if (dstat & DSTAT_IID) {
- /* This can be due to a quick reselect while doing a WAIT
- * DISCONNECT.
- */
- resume_offset = handle_idd(host, cmd);
- }
- else {
- sim710_errors++;
- printk("scsi%d: Spurious interrupt!\n", host->host_no);
- /* resume_offset is zero, which will cause a host reset */
- }
- }
+ /* Fill in the three required pieces of hostdata */
+ hostdata->base = base_addr;
+ hostdata->differential = differential;
+ hostdata->clock = clock;
+ hostdata->chip710 = 1;
- if (resume_offset) {
- if (resume_offset == Ent_reselect) {
- hostdata->running = NULL;
- hostdata->state = STATE_IDLE;
+ /* and register the chip */
+ if((host = NCR_700_detect(sim710_global_info.tpnt, hostdata)) == NULL) {
+ printk(KERN_ERR "sim710: No host detected; card configuration problem?\n");
+ goto out_release;
}
- else
- hostdata->state = STATE_BUSY;
- DEB(DEB_RESUME, printk("scsi%d: Resuming at script[0x%x]\n",
- host->host_no, resume_offset/4));
-#ifdef DEBUG_LIMIT_INTS
- if (sim710_intrs < DEBUG_LIMIT_INTS)
-#endif
- {
- NCR_write32(SCRATCH_REG, 0);
- NCR_write32(DSP_REG,
- isa_virt_to_bus(hostdata->script+resume_offset/4));
- }
- if (resume_offset == Ent_reselect)
- run_process_issue_queue(hostdata);
- }
- else {
- printk("scsi%d: Failed to handle interrupt. Failing commands "
- "and resetting SCSI bus and chip\n", host->host_no);
- mdelay(1000); /* Give chance to read screen!! */
- full_reset(host);
- }
-
-}
+ host->irq = irq;
+ host->this_id = scsi_id;
-static void
-run_command (struct sim710_hostdata *hostdata, Scsi_Cmnd *cmd)
-{
- struct Scsi_Host *host = cmd->host;
- struct sim710_target *targdata = hostdata->target + cmd->target;
- int i, datain, dataout, sg_start;
- u32 *dip, *dop, dsa;
-
- DEB(DEB_CMND, printk("scsi%d: id%d starting ", host->host_no,
- cmd->target));
- DEB(DEB_CMND, print_command(cmd->cmnd));
-
- switch (cmd->cmnd[0]) {
- case INQUIRY:
- case MODE_SENSE:
- case READ_6:
- case READ_10:
- case READ_CAPACITY:
- case REQUEST_SENSE:
- case READ_BLOCK_LIMITS:
- case READ_TOC:
- datain = 1;
- dataout = 0;
- break;
- case MODE_SELECT:
- case WRITE_6:
- case WRITE_10:
- datain = 0;
- dataout = 1;
- break;
- case TEST_UNIT_READY:
- case ALLOW_MEDIUM_REMOVAL:
- case START_STOP:
- datain = dataout = 0;
- break;
- default:
- datain = dataout = 1;
- }
-
- memcpy(targdata->dsa_cdb, cmd->cmnd, MAX_CMND);
-
- targdata->dsa_msgout[0] =
- IDENTIFY((opt_nodisc[hostdata->chip] & (1<<cmd->target)) ? 0 : 1 ,0);
- if (hostdata->negotiate & (1 << cmd->target)) {
- if (opt_noneg[hostdata->chip] & (1 << cmd->target)) {
- hostdata->negotiate ^= (1 << cmd->target);
- targdata->dsa[DSA_MSGOUT] = 1;
- }
- else {
- DEB(DEB_SYNC, printk("scsi%d: Negotiating async transfers "
- "for ID %d\n",
- host->host_no, cmd->target));
- memcpy(targdata->dsa_msgout+1, async_message, sizeof(async_message));
- targdata->dsa[DSA_MSGOUT] = sizeof(async_message) + 1;
- }
- }
- else
- targdata->dsa[DSA_MSGOUT] = 1;
-
- targdata->dsa_msgin[0] = 0xff;
- targdata->dsa_status[0] = 0xff;
-
- targdata->dsa[DSA_SELECT] = (1 << cmd->target) << 16;
- targdata->dsa[DSA_MSGOUT+1] = isa_virt_to_bus(targdata->dsa_msgout);
- targdata->dsa[DSA_CMND] = cmd->cmd_len;
- targdata->dsa[DSA_CMND+1] = isa_virt_to_bus(targdata->dsa_cdb);
- targdata->dsa[DSA_STATUS] = 1;
- targdata->dsa[DSA_STATUS+1] = isa_virt_to_bus(targdata->dsa_status);
- targdata->dsa[DSA_MSGIN] = 1;
- targdata->dsa[DSA_MSGIN+1] = isa_virt_to_bus(targdata->dsa_msgin);
-
- sg_start = (MAX_SG - (cmd->use_sg ? cmd->use_sg : 1)) * 2;
- dip = targdata->dsa + DSA_DATAIN + sg_start;
- dop = targdata->dsa + DSA_DATAOUT + sg_start;
-
- for (i = 0; cmd->use_sg ? (i < cmd->use_sg) : !i; i++) {
- struct scatterlist *sgl = &((struct scatterlist *)cmd->buffer)[i];
- void *vbuf = cmd->use_sg ?
- (page_address(sgl->page) + sgl->offset) :
- (cmd->request_buffer);
- u32 bbuf = isa_virt_to_bus(vbuf);
- u32 cnt = cmd->use_sg ? sgl->length : cmd->request_bufflen;
-
- if (datain) {
- *dip++ = cnt;
- *dip++ = bbuf;
- }
- if (dataout) {
- *dop++ = cnt;
- *dop++ = bbuf;
+ if(request_irq(irq, NCR_700_intr, SA_SHIRQ, "sim710", host)) {
+ printk(KERN_ERR "sim710: irq problem with %d, detaching\n",
+ irq);
+ goto out_unregister;
}
- }
- targdata->data_out_jump = hostdata->script[Ent_patch_output_data/4+1] =
- isa_virt_to_bus(hostdata->script + Ent_patch_output_data/4 + sg_start + 2);
- targdata->data_in_jump = hostdata->script[Ent_patch_input_data/4+1] =
- isa_virt_to_bus(hostdata->script + Ent_patch_input_data/4 + sg_start + 2);
-
- for (i = 0, dsa = isa_virt_to_bus(targdata->dsa); i < 4; i++) {
- u32 v = hostdata->script[Ent_patch_new_dsa/4 + i * 2];
-
- v &= ~0x0000ff00;
- v |= (dsa & 0xff) << 8;
- hostdata->script[Ent_patch_new_dsa/4 + i * 2] = v;
- dsa >>= 8;
- }
- hostdata->running = targdata->cur_cmd = cmd;
- hostdata->state = STATE_BUSY;
- NCR_write8(ISTAT_REG, ISTAT_10_SIGP);
-}
-
-
-static volatile int process_issue_queue_running = 0;
-
-static __inline__ void
-run_process_issue_queue(struct sim710_hostdata *hostdata)
-{
- unsigned long flags;
- save_flags (flags);
- cli();
- if (!process_issue_queue_running) {
- process_issue_queue_running = 1;
- process_issue_queue(hostdata, flags);
- /*
- * process_issue_queue_running is cleared in process_issue_queue
- * once it can't do more work, and process_issue_queue exits with
- * interrupts disabled.
- */
- }
- restore_flags (flags);
-}
+ scsi_set_device(host, dev);
+ hostdata->dev = dev;
+ sim710_global_info.found++;
-/*
- * Function : process_issue_queue (hostdata, flags)
- *
- * Purpose : Start next command for any idle target.
- *
- * NOTE : process_issue_queue exits with interrupts *disabled*, so the
- * caller must reenable them if it desires.
- *
- * NOTE : process_issue_queue should be called from both
- * sim710_queue_command() and from the interrupt handler
- * after command completion.
- */
-
-static void
-process_issue_queue (struct sim710_hostdata *hostdata, unsigned long flags)
-{
- Scsi_Cmnd *tmp, *prev;
- int done;
-
- /*
- * We run (with interrupts disabled) until we're sure that none of
- * the host adapters have anything that can be done, at which point
- * we set process_issue_queue_running to 0 and exit.
- *
- * Interrupts are enabled before doing various other internal
- * instructions, after we've decided that we need to run through
- * the loop again.
- *
- */
-
- do {
- cli(); /* Freeze request queues */
- done = 1;
- if (hostdata->issue_queue) {
- if (hostdata->state == STATE_DISABLED) {
- tmp = (Scsi_Cmnd *) hostdata->issue_queue;
- hostdata->issue_queue = (Scsi_Cmnd *) tmp->SCp.ptr;
- tmp->result = (DID_BAD_TARGET << 16);
- tmp->scsi_done (tmp);
- done = 0;
- }
- else if (hostdata->state == STATE_IDLE) {
- for (tmp = hostdata->issue_queue, prev = NULL; tmp;
- prev = tmp, tmp = (Scsi_Cmnd *) tmp->SCp.ptr) {
- if (hostdata->target[tmp->target].cur_cmd == NULL) {
- if (prev)
- prev->SCp.ptr = tmp->SCp.ptr;
- else
- hostdata->issue_queue = (Scsi_Cmnd *) tmp->SCp.ptr;
- tmp->SCp.ptr = NULL;
- run_command (hostdata, tmp);
- done = 0;
- } /* if target/lun is not busy */
- } /* scan issue queue for work */
- } /* host is idle */
- } /* if hostdata->issue_queue */
- if (!done)
- restore_flags (flags);
- } while (!done);
- process_issue_queue_running = 0;
-}
-
-
-int
-sim710_queuecommand(Scsi_Cmnd * cmd, void (*done)(Scsi_Cmnd *))
-{
- struct Scsi_Host *host = cmd->host;
- struct sim710_hostdata *hostdata = (struct sim710_hostdata *)host->hostdata[0];
- Scsi_Cmnd *tmp;
- unsigned long flags;
-
- if (cmd->lun) {
- /* Silently ignore luns other than zero! */
- cmd->result = (DID_BAD_TARGET << 16);
- done(cmd);
- return 0;
- }
-
- DEB(DEB_CMND, printk("scsi%d: id%d queuing ", host->host_no,
- cmd->target));
- DEB(DEB_CMND, print_command(cmd->cmnd));
-
- cmd->scsi_done = done;
- cmd->host_scribble = NULL;
- cmd->SCp.ptr = NULL;
- cmd->SCp.buffer = NULL;
-
- save_flags(flags);
- cli();
-
- if (ignore_ids[hostdata->chip] & (1 << cmd->target)) {
- printk("scsi%d: ignoring target %d\n", host->host_no, cmd->target);
- cmd->result = (DID_BAD_TARGET << 16);
- done(cmd);
- restore_flags (flags);
- return 0;
- }
-#ifdef DEBUG_LIMIT_INTS
- if (sim710_intrs > DEBUG_LIMIT_INTS) {
- cmd->result = (DID_BAD_TARGET << 16);
- done(cmd);
- restore_flags (flags);
return 0;
- }
-#endif
- if (cmd->use_sg > MAX_SG)
- panic ("cmd->use_sg = %d\n", cmd->use_sg);
- if (!(hostdata->issue_queue) || (cmd->cmnd[0] == REQUEST_SENSE)) {
- cmd->SCp.ptr = (unsigned char *) hostdata->issue_queue;
- hostdata->issue_queue = cmd;
- } else {
- for (tmp = hostdata->issue_queue; tmp->SCp.ptr;
- tmp = (Scsi_Cmnd *) tmp->SCp.ptr);
- tmp->SCp.ptr = (unsigned char *) cmd;
- }
- restore_flags (flags);
- run_process_issue_queue(hostdata);
- return 0;
+ out_unregister:
+ scsi_unregister(host);
+ out_release:
+ release_region(host->base, 64);
+ out_free:
+ kfree(hostdata);
+ out:
+ return -ENODEV;
}
+#ifdef CONFIG_MCA
+static short sim710_mca_id_table[] = { 0x01bb, 0x01ba, 0x004f, 0};
__init int
-sim710_detect(Scsi_Host_Template * tpnt)
+sim710_mca_probe(struct device *dev)
{
- unsigned char scsi_id;
- unsigned int base_addr;
- struct Scsi_Host * host = NULL;
- struct sim710_hostdata *hostdata;
- unsigned long timeout;
- unsigned long irq_mask;
- int requested_irq;
- int probed_irq;
- u32 dsps;
- int chips = 0;
- int limit;
- int indx;
- int revision;
- int size;
- volatile u8 tmp;
- struct Scsi_Host *our_hosts[MAXBOARDS+1];
-
-#ifdef MODULE
- if (sim710)
- param_setup(sim710);
-#endif
-
- if (no_of_boards < 0) {
- printk("sim710: NCR53C710 driver disabled\n");
- return 0;
- }
-
-#ifdef CONFIG_MCA
- /* If board details have been specified via boot/module parameters,
- * then don't bother probing.
- */
- if (no_of_boards == 0) {
- int slot;
+ struct mca_device *mca_dev = to_mca_device(dev);
+ int slot = mca_dev->slot;
int pos[3];
- int mca_53c710_ids[] = MCA_53C710_IDS;
- int *id_to_check = mca_53c710_ids;
+ unsigned int base;
+ int irq_vector;
+ short id = sim710_mca_id_table[mca_dev->index];
static int io_004f_by_pos[] = MCA_004F_IO_PORTS;
static int irq_004f_by_pos[] = MCA_004F_IRQS;
static int io_01bb_by_pos[] = MCA_01BB_IO_PORTS;
static int irq_01bb_by_pos[] = MCA_01BB_IRQS;
+ char *name;
+ int clock;
- while ( *id_to_check && no_of_boards < MAXBOARDS) {
- if (!MCA_bus)
- return 0;
-
- if ((slot = mca_find_adapter(*id_to_check, 0)) != MCA_NOTFOUND) {
-
- pos[0] = mca_read_stored_pos(slot, 2);
- pos[1] = mca_read_stored_pos(slot, 3);
- pos[2] = mca_read_stored_pos(slot, 4);
-
- /*
- * 01BB & 01BA port base by bits 7,6,5,4,3,2 in pos[2]
- *
- * 000000 <disabled> 001010 0x2800
- * 000001 <invalid> 001011 0x2C00
- * 000010 0x0800 001100 0x3000
- * 000011 0x0C00 001101 0x3400
- * 000100 0x1000 001110 0x3800
- * 000101 0x1400 001111 0x3C00
- * 000110 0x1800 010000 0x4000
- * 000111 0x1C00 010001 0x4400
- * 001000 0x2000 010010 0x4800
- * 001001 0x2400 010011 0x4C00
- * 010100 0x5000
- *
- * 00F4 port base by bits 3,2,1 in pos[0]
- *
- * 000 <disabled> 001 0x200
- * 010 0x300 011 0x400
- * 100 0x500 101 0x600
- *
- * 01BB & 01BA IRQ is specified in pos[0] bits 7 and 6:
- *
- * 00 3 10 11
- * 01 5 11 14
- *
- * 00F4 IRQ specified by bits 6,5,4 in pos[0]
- *
- * 100 5 101 9
- * 110 14
- */
-
- if ( *id_to_check == 0x01bb || *id_to_check == 0x01ba ) {
- bases[no_of_boards] = io_01bb_by_pos[(pos[2] & 0xFC) >> 2];
- irq_vectors[no_of_boards] =
- irq_01bb_by_pos[((pos[0] & 0xC0) >> 6)];
- if (bases[no_of_boards] == 0x0000)
- printk("sim710: NCR53C710 Adapter ID 0x01bb is disabled.\n");
- else {
- no_of_boards++;
- if ( *id_to_check == 0x01bb )
- mca_set_adapter_name( slot,
- "NCR 3360/3430 SCSI SubSystem" );
- else
- mca_set_adapter_name(slot,
- "NCR Dual SIOP SCSI Host Adapter Board");
- }
- }
- else if ( *id_to_check == 0x004f ) {
- bases[no_of_boards] = io_004f_by_pos[((pos[0] & 0x0E) >> 1)];
- irq_vectors[no_of_boards] =
- irq_004f_by_pos[((pos[0] & 0x70) >> 4) - 4];
- if (bases[no_of_boards] == 0x0000)
- printk("sim710: NCR53C710 Adapter ID 0x004f is disabled.\n");
- else {
- no_of_boards++;
- mca_set_adapter_name(slot,
- "NCR 53c710 SCSI Host Adapter Board");
- }
- }
- }
- id_to_check++;
- }
- }
-#endif
+ pos[0] = mca_device_read_stored_pos(mca_dev, 2);
+ pos[1] = mca_device_read_stored_pos(mca_dev, 3);
+ pos[2] = mca_device_read_stored_pos(mca_dev, 4);
-#ifdef CONFIG_EISA
- /* Auto probe, if no boards specified in boot parameters */
- if (no_of_boards == 0) {
- int io_addr;
- /* reverse probe, so my on-board controller at 0x9000 is always scsi0 */
- for (io_addr = 0x9000; no_of_boards < MAXBOARDS && io_addr >= 0x1000; io_addr -= 0x1000) {
- if (request_region(io_addr, 0x40, "sim710") != NULL) {
- int id0 = inw(io_addr + 0xc80);
- int id1 = inw(io_addr + 0xc82);
- /* The on-board controller on my Proliant 2000 is 0x1044,
- * my EISA card is 0x1144.
- */
- if (id0 == 0x110e && (id1 == 0x1044 || id1 == 0x1144)) {
- bases[no_of_boards] = io_addr;
-#if 0
- /* This should detect the IRQ, but I havn't proved it for
- * myself. Leave the old probe code active for now, as
- * no-one has reported problems with it.
- */
- switch (inb(io_addr + 0xc88)) {
- case (0x00):
- irq_vectors[no_of_boards] = 11;
- break;
- case (0x01):
- irq_vectors[no_of_boards] = 14;
- break;
- case (0x02):
- irq_vectors[no_of_boards] = 15;
- break;
- case (0x03):
- irq_vectors[no_of_boards] = 10;
- break;
- case (0x04):
- irq_vectors[no_of_boards] = 9;
- break;
- default:
- printk("sim710.c: irq nasty\n");
- }
-#endif
- no_of_boards++;
- }
- release_region(io_addr, 64);
- }
- }
- }
-#endif
-
- if (!no_of_boards) {
- printk("sim710: No NCR53C710 adapter found.\n");
- return 0;
- }
-
- size = sizeof(struct sim710_hostdata);
- hostdata_order = 0;
- while (size > (PAGE_SIZE << hostdata_order))
- hostdata_order++;
- size = PAGE_SIZE << hostdata_order;
-
- DEB(DEB_ANY, printk("sim710: hostdata %d bytes, size %d, order %d\n",
- sizeof(struct sim710_hostdata), size, hostdata_order));
-
- tpnt->proc_name = "sim710";
-
- memset(our_hosts, 0, sizeof(our_hosts));
- for (indx = 0; indx < no_of_boards; indx++) {
- unsigned long page = __get_free_pages(GFP_ATOMIC, hostdata_order);
- if(page == 0UL)
- {
- printk(KERN_WARNING "sim710: out of memory registering board %d.\n", indx);
- break;
- }
- host = scsi_register(tpnt, 4);
- if(host == NULL) {
- free_pages(host->hostdata[0], hostdata_order);
- break;
- }
- our_hosts[chips] = host;
- host->hostdata[0] = page;
- hostdata = (struct sim710_hostdata *)host->hostdata[0];
- memset(hostdata, 0, size);
- scsi_id = 7;
- base_addr = bases[indx];
- requested_irq = irq_vectors[indx];
- printk("scsi%d: Configuring Sim710 (SCSI-ID %d) at %x, IRQ %d\n",
- host->host_no, scsi_id, base_addr, requested_irq);
- DEB(DEB_ANY, printk("sim710: hostdata = %p (%d bytes), dsa0 = %p\n",
- hostdata, sizeof(struct sim710_hostdata),
- hostdata->target[0].dsa));
- hostdata->chip = indx;
- host->irq = requested_irq;
- host->this_id = scsi_id;
- host->unique_id = base_addr;
- host->base = base_addr;
- hostdata->msg_reject = MESSAGE_REJECT;
-
- if (ncr_halt(host)) {
- free_pages(host->hostdata[0], hostdata_order);
- scsi_unregister (host);
- printk("scsi%d: Failed to initialise 53c710 at address %x\n",
- host->host_no, base_addr);
- continue;
- }
- DEB(DEB_ANY,ncr_dump(host));
- revision = (NCR_read8(CTEST8_REG) & 0xF0) >> 4;
- printk("scsi%d: Revision 0x%x\n",host->host_no,revision);
- sim710_soft_reset(host);
-
- sim710_driver_init(host);
-
- request_region((u32)host->base, 64, "sim710");
- /* Now run test1 */
- hostdata->test1_src = 0x53c710aa;
- hostdata->test1_dst = 0x76543210;
- NCR_write32(DSPS_REG, 0x89abcdef);
- irq_mask = probe_irq_on();
- NCR_write32(DSP_REG, virt_to_bus(hostdata->script+Ent_test1/4));
- timeout = 5;
- while (hostdata->test1_dst != hostdata->test1_src && timeout--)
- mdelay(100);
- tmp = NCR_read8(ISTAT_REG);
- tmp = NCR_read8(SSTAT0_REG);
- udelay(10);
- tmp = NCR_read8(DSTAT_REG);
- probed_irq = probe_irq_off(irq_mask);
- if (requested_irq == 0) {
- if (probed_irq > 0) {
- printk("scsi%d: Chip is using IRQ %d\n", host->host_no,
- probed_irq);
- requested_irq = host->irq = probed_irq;
- }
- else {
- printk("scsi%d: Failed to probe for IRQ (returned %d)\n",
- host->host_no, probed_irq);
- ncr_halt(host);
- free_pages(host->hostdata[0], hostdata_order);
- scsi_unregister (host);
- release_region((u32)host->base, 64);
- continue;
- }
- }
- else if (probed_irq > 0 && probed_irq != requested_irq)
- printk("scsi%d: WARNING requested IRQ %d, but probed as %d\n",
- host->host_no, requested_irq, probed_irq);
- else if (probed_irq <= 0)
- printk("scsi%d: WARNING IRQ probe failed, (returned %d)\n",
- host->host_no, probed_irq);
-
- dsps = NCR_read32(DSPS_REG);
- if (hostdata->test1_dst != 0x53c710aa || dsps != A_int_test1) {
- if (hostdata->test1_dst != 0x53c710aa)
- printk("scsi%d: test 1 FAILED: data: exp 0x53c710aa, got 0x%08x\n",
- host->host_no, hostdata->test1_dst);
- if (dsps != A_int_test1)
- printk("scsi%d: test 1 FAILED: dsps: exp 0x%08x, got 0x%08x\n",
- host->host_no, A_int_test1, dsps);
- ncr_dump(host);
- ncr_halt(host);
- free_pages(host->hostdata[0], hostdata_order);
- scsi_unregister (host);
- release_region((u32)host->base, 64);
- continue;
- }
- printk("scsi%d: test 1 completed ok.\n", host->host_no);
-
- NCR_write32(DSP_REG, virt_to_bus(hostdata->script+Ent_reselect/4));
- hostdata->state = STATE_IDLE;
- chips++;
- }
- /* OK, now run down our_hosts[] calling request_irq(... SA_SHIRQ ...).
- * Couldn't call request_irq earlier, as probing would have failed.
- */
- for (indx = 0, limit = chips; indx < limit; indx++) {
- host = our_hosts[indx];
- if (request_irq(host->irq, do_sim710_intr_handle,
- SA_INTERRUPT | SA_SHIRQ, "sim710", host))
- {
- printk("scsi%d : IRQ%d not free, detaching\n",
- host->host_no, host->irq);
- ncr_halt(host);
- free_pages(host->hostdata[0], hostdata_order);
- scsi_unregister (host);
- chips--;
- }
- }
-
- return chips;
-}
+ /*
+ * 01BB & 01BA port base by bits 7,6,5,4,3,2 in pos[2]
+ *
+ * 000000 <disabled> 001010 0x2800
+ * 000001 <invalid> 001011 0x2C00
+ * 000010 0x0800 001100 0x3000
+ * 000011 0x0C00 001101 0x3400
+ * 000100 0x1000 001110 0x3800
+ * 000101 0x1400 001111 0x3C00
+ * 000110 0x1800 010000 0x4000
+ * 000111 0x1C00 010001 0x4400
+ * 001000 0x2000 010010 0x4800
+ * 001001 0x2400 010011 0x4C00
+ * 010100 0x5000
+ *
+ * 00F4 port base by bits 3,2,1 in pos[0]
+ *
+ * 000 <disabled> 001 0x200
+ * 010 0x300 011 0x400
+ * 100 0x500 101 0x600
+ *
+ * 01BB & 01BA IRQ is specified in pos[0] bits 7 and 6:
+ *
+ * 00 3 10 11
+ * 01 5 11 14
+ *
+ * 00F4 IRQ specified by bits 6,5,4 in pos[0]
+ *
+ * 100 5 101 9
+ * 110 14
+ */
-int
-sim710_abort(Scsi_Cmnd * cmd)
-{
- struct Scsi_Host * host = cmd->host;
+ if (id == 0x01bb || id == 0x01ba) {
+ base = io_01bb_by_pos[(pos[2] & 0xFC) >> 2];
+ irq_vector =
+ irq_01bb_by_pos[((pos[0] & 0xC0) >> 6)];
+
+ clock = 50;
+ if (id == 0x01bb)
+ name = "NCR 3360/3430 SCSI SubSystem";
+ else
+ name = "NCR Dual SIOP SCSI Host Adapter Board";
+ } else if ( id == 0x004f ) {
+ base = io_004f_by_pos[((pos[0] & 0x0E) >> 1)];
+ irq_vector =
+ irq_004f_by_pos[((pos[0] & 0x70) >> 4) - 4];
+ clock = 50;
+ name = "NCR 53c710 SCSI Host Adapter Board";
+ } else {
+ return -ENODEV;
+ }
+ strncpy(dev->name, name, sizeof(dev->name));
+ mca_device_set_claim(mca_dev, 1);
+ base = mca_device_transform_ioport(mca_dev, base);
+ irq_vector = mca_device_transform_irq(mca_dev, irq_vector);
+
+ return sim710_probe_common(dev, base, irq_vector, clock,
+ 0, id_array[slot]);
+}
+
+struct mca_driver sim710_mca_driver = {
+ .id_table = sim710_mca_id_table,
+ .driver = {
+ .name = "sim710",
+ .bus = &mca_bus_type,
+ .probe = sim710_mca_probe,
+ },
+};
- printk("scsi%d: Unable to abort command for target %d\n",
- host->host_no, cmd->target);
- return FAILED;
-}
+#endif /* CONFIG_MCA */
-/*
- * This is a device reset. Need to select and send a Bus Device Reset msg.
- */
+#ifdef CONFIG_EISA
+struct eisa_device_id sim710_eisa_ids[] = {
+ { "CPQ4410" },
+ { "CPQ4411" },
+ { "HWP0C80" },
+ { "" }
+};
-int
-sim710_dev_reset(Scsi_Cmnd * SCpnt)
+__init int
+sim710_eisa_probe(struct device *dev)
{
- struct Scsi_Host * host = SCpnt->host;
+ struct eisa_device *edev = to_eisa_device(dev);
+ unsigned long io_addr = edev->base_addr;
+ char eisa_cpq_irqs[] = { 11, 14, 15, 10, 9, 0 };
+ char eisa_hwp_irqs[] = { 3, 4, 5, 7, 12, 10, 11, 0};
+ char *eisa_irqs;
+ unsigned char irq_index;
+ unsigned char irq, differential = 0, scsi_id = 7;
+
+ if(strcmp(edev->id.sig, "HWP0C80") == 0) {
+ printk(KERN_NOTICE "sim710: FOUND HP CARD!\n");
+ eisa_irqs = eisa_hwp_irqs;
+ irq_index = (inb(io_addr + 0xc85) & 0x7) - 1;
+ scsi_id = ffs(inb(io_addr + 0x4));
+ } else {
+ eisa_irqs = eisa_cpq_irqs;
+ irq_index = inb(io_addr + 0xc88);
+ }
+
+ printk(KERN_NOTICE "IRQ_INDEX %d, %d\n", irq_index,
+ strlen(eisa_irqs));
+
+ if(irq_index >= strlen(eisa_irqs)) {
+ printk("sim710.c: irq nasty\n");
+ return -ENODEV;
+ }
+
+ irq = eisa_irqs[irq_index];
+
+ return sim710_probe_common(dev, io_addr, irq, 50,
+ differential, scsi_id);
+}
+
+struct eisa_driver sim710_eisa_driver = {
+ .id_table = sim710_eisa_ids,
+ .driver = {
+ .name = "sim710",
+ .probe = sim710_eisa_probe,
+ .remove = __devexit_p(sim710_device_remove),
+ },
+};
- printk("scsi%d: Unable to send Bus Device Reset for target %d\n",
- host->host_no, SCpnt->target);
- return FAILED;
-}
+#endif /* CONFIG_EISA */
-/*
- * This is bus reset. We need to reset the bus and fail any active commands.
- */
int
-sim710_bus_reset(Scsi_Cmnd * SCpnt)
-{
- struct Scsi_Host * host = SCpnt->host;
-
- printk("scsi%d: Unable to do SCSI bus reset\n", host->host_no);
- return FAILED;
-}
-
-static int
-full_reset(struct Scsi_Host * host)
+sim710_release(struct Scsi_Host *host)
{
- struct sim710_hostdata *hostdata = (struct sim710_hostdata *)
- host->hostdata[0];
- int target;
- Scsi_Cmnd *cmd;
-
- u32 istat, dstat = 0, sstat0 = 0, sstat1 = 0, dsp, dsps, scratch;
- unsigned long flags;
-
- save_flags(flags);
- cli();
-
- istat = NCR_read8(ISTAT_REG);
- if (istat & ISTAT_SIP) {
- sstat0 = NCR_read8(SSTAT0_REG);
- sstat1 = NCR_read8(SSTAT1_REG);
- udelay(10);
- }
- if (istat & ISTAT_DIP)
- dstat = NCR_read8(DSTAT_REG);
-
- if (ncr_halt(host)) {
- restore_flags(flags);
- return FAILED;
- }
- restore_flags(flags);
- dsp = NCR_read32(DSP_REG);
- dsps = NCR_read32(DSPS_REG);
- scratch = NCR_read32(SCRATCH_REG);
- printk("scsi%d: istat = %02x, sstat0 = %02x, sstat1 = %02x, dstat = %02x\n",
- host->host_no, istat, sstat0, sstat1, dstat);
- printk("scsi%d: dsp = %08x (script[0x%04x]), dsps = %08x, scratch = %08x\n",
- host->host_no, dsp,
- ((u32)bus_to_virt(dsp) - (u32)hostdata->script)/4, dsps, scratch);
-
- for (target = 0; target < 7; target++) {
- if ((cmd = hostdata->target[target].cur_cmd)) {
- printk("scsi%d: Failing command for ID%d\n",
- host->host_no, target);
- cmd->result = DID_RESET << 16;
- cmd->scsi_done(cmd);
- hostdata->target[target].cur_cmd = NULL;
- }
- }
+ struct D700_Host_Parameters *hostdata =
+ (struct D700_Host_Parameters *)host->hostdata[0];
- sim710_soft_reset(host);
- sim710_driver_init(host);
-
- NCR_write32(DSP_REG, isa_virt_to_bus(hostdata->script+Ent_reselect/4));
- hostdata->state = STATE_IDLE;
-
- run_process_issue_queue(hostdata);
-
- return SUCCESS;
+ NCR_700_release(host);
+ kfree(hostdata);
+ free_irq(host->irq, host);
+ /* should do a refcount here and unregister the drivers when
+ * it reaches zero */
+ return 1;
}
-/*
- * This is host reset. We need to reset the chip and the bus.
- */
-
-int
-sim710_host_reset(Scsi_Cmnd * SCpnt)
+int __init
+sim710_detect(Scsi_Host_Template *tpnt)
{
- struct Scsi_Host * host = SCpnt->host;
-
- printk("scsi%d: >>>>>>>>>>>> Host reset <<<<<<<<<<<<\n", host->host_no);
-
- return full_reset(host);
-}
+ sim710_global_info.tpnt = tpnt;
+ sim710_global_info.found = 0;
#ifdef MODULE
+ if (sim710)
+ param_setup(sim710);
+#endif
-int
-sim710_release(struct Scsi_Host *host)
-{
- ncr_halt(host);
- free_pages(host->hostdata[0], hostdata_order);
- free_irq(host->irq, host);
- release_region((u32)host->base, 64);
- return 1;
-}
+#ifdef CONFIG_MCA
+ if(MCA_bus)
+ mca_register_driver(&sim710_mca_driver);
+#endif
+#ifdef CONFIG_EISA
+ eisa_driver_register(&sim710_eisa_driver);
#endif
+ return sim710_global_info.found;
+}
-static Scsi_Host_Template driver_template = SIM710_SCSI;
+static Scsi_Host_Template driver_template = {
+ .name = "LSI (Symbios) 710 MCA/EISA",
+ .proc_name = "sim710",
+ .detect = sim710_detect,
+ .release = sim710_release,
+ .this_id = 7,
+};
#include "scsi_module.c"
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH 2.5.59] sim710: cleanup/remove most cli()'s
2003-02-08 3:57 ` James Bottomley
@ 2003-02-11 10:55 ` Rolf Eike Beer
2003-02-11 18:30 ` James Bottomley
0 siblings, 1 reply; 9+ messages in thread
From: Rolf Eike Beer @ 2003-02-11 10:55 UTC (permalink / raw)
To: James Bottomley; +Cc: linux-scsi
Am Samstag, 8. Februar 2003 04:57 schrieben Sie:
> On Fri, 2003-02-07 at 01:26, Rolf Eike Beer wrote:
> > That would be fine, you know your code better than I ever will.
>
> OK, the attached works for me for the 3430 MCA internal SCSI chip and an
> HP EISA SCSI board. Let me know how it works for the Compaq.
This is from my boot.msg:
<6>EISA bus registered
<6>EISA: Probing bus...
<6>EISA: Motherboard CPQ0601 detected
<6>EISA: slot 2 : CPQ3011 detected.
<6>EISA: slot 3 : CPQ6100 detected.
<6>EISA: slot 7 : CPQ4411 detected.
<6>EISA: slot 8 : CPQ4410 detected.
<6>EISA: Detected 4 cards.
[...]
<5>IRQ_INDEX 249, 5
<4>sim710: irq nasty
This is the Compaq NCR 53c710 on an EISA board, address 0x7000, IRQ 14 (and it
works fine with the original sim710).
<5>IRQ_INDEX 2, 5
<5>sim710: Compaq Integrated 32-Bit Fast-SCSI-2 Controller
<5>sim710: irq = 15, clock = 50, base = 0x8000, scsi_id = 7
<5>53c700: Version 2.8 By James.Bottomley@HansenPartnership.com
<5>scsi0: 53c710 rev 2
<6>scsi0 : LSI (Symbios) 710 MCA/EISA
<6>scsi0: (0:0) Synchronous at offset 8, period 100ns
<5> Vendor: SEAGATE Model: ST51080N Rev: 0943
<5> Type: Direct-Access ANSI SCSI revision: 02
<6>scsi0: (1:0) Synchronous at offset 8, period 100ns
<5> Vendor: SEAGATE Model: ST51080N Rev: 0943
<5> Type: Direct-Access ANSI SCSI revision: 02
<6>scsi0: (2:0) Synchronous at offset 8, period 100ns
<5> Vendor: COMPAQ Model: M2694ES-512 Rev: 952D
<5> Type: Direct-Access ANSI SCSI revision: 02
<6>scsi0: (3:0) Synchronous at offset 8, period 100ns
<5> Vendor: COMPAQ Model: M2694ES-512 Rev: 952D
<5> Type: Direct-Access ANSI SCSI revision: 02
<6>scsi0: (0:0) Enabling Tag Command Queuing
And this is the onboard NCR53c710. Works fine so far. Now we have to find a
way to get the other board working, I want to use my external drive, too.
I'll send some minor changes I made to the new code tomorrow or so.
Eike
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH 2.5.59] sim710: cleanup/remove most cli()'s
2003-02-11 10:55 ` Rolf Eike Beer
@ 2003-02-11 18:30 ` James Bottomley
0 siblings, 0 replies; 9+ messages in thread
From: James Bottomley @ 2003-02-11 18:30 UTC (permalink / raw)
To: Rolf Eike Beer; +Cc: SCSI Mailing List
[-- Attachment #1: Type: text/plain, Size: 1157 bytes --]
On Tue, 2003-02-11 at 04:55, Rolf Eike Beer wrote:
> Am Samstag, 8. Februar 2003 04:57 schrieben Sie:
> > On Fri, 2003-02-07 at 01:26, Rolf Eike Beer wrote:
> > > That would be fine, you know your code better than I ever will.
> >
> > OK, the attached works for me for the 3430 MCA internal SCSI chip and an
> > HP EISA SCSI board. Let me know how it works for the Compaq.
>
> This is from my boot.msg:
>
> <6>EISA bus registered
> <6>EISA: Probing bus...
> <6>EISA: Motherboard CPQ0601 detected
> <6>EISA: slot 2 : CPQ3011 detected.
> <6>EISA: slot 3 : CPQ6100 detected.
> <6>EISA: slot 7 : CPQ4411 detected.
> <6>EISA: slot 8 : CPQ4410 detected.
> <6>EISA: Detected 4 cards.
>
> [...]
>
> <5>IRQ_INDEX 249, 5
> <4>sim710: irq nasty
>
> This is the Compaq NCR 53c710 on an EISA board, address 0x7000, IRQ 14 (and it
> works fine with the original sim710).
Ah, OK, that's what I get for enabling something that was previously
disabled. I suspected the disabled probe code had more than just the
IRQ coded into it. It looks like only the three lower bits should be
used to determine the IRQ. I believe it will work if you apply this
patch.
James
[-- Attachment #2: tmp.diff --]
[-- Type: text/plain, Size: 368 bytes --]
===== drivers/scsi/sim710.c 1.8 vs edited =====
--- 1.8/drivers/scsi/sim710.c Sun Feb 9 10:07:34 2003
+++ edited/drivers/scsi/sim710.c Tue Feb 11 12:28:55 2003
@@ -307,7 +307,7 @@
#endif
} else {
eisa_irqs = eisa_cpq_irqs;
- irq_index = inb(io_addr + 0xc88);
+ irq_index = inb(io_addr + 0xc88) & 0x07;
}
if(irq_index >= strlen(eisa_irqs)) {
^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2003-02-11 18:30 UTC | newest]
Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2003-02-04 10:23 [PATCH 2.5.59] sim710: cleanup/remove most cli()'s Rolf Eike Beer
2003-02-04 11:34 ` Christoph Hellwig
2003-02-04 23:11 ` James Bottomley
2003-02-05 15:03 ` Rolf Eike Beer
2003-02-06 16:35 ` James Bottomley
2003-02-07 7:26 ` Rolf Eike Beer
2003-02-08 3:57 ` James Bottomley
2003-02-11 10:55 ` Rolf Eike Beer
2003-02-11 18:30 ` James Bottomley
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox