All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v4 00/23] ncr5380: Eliminate macros, reduce code duplication, fix bugs etc
@ 2016-03-23 10:10 ` Finn Thain
  0 siblings, 0 replies; 60+ messages in thread
From: Finn Thain @ 2016-03-23 10:10 UTC (permalink / raw)
  To: James E.J. Bottomley, Martin K. Petersen, Michael Schmitz,
	linux-m68k, linux-scsi, linux-kernel
  Cc: Ondrej Zary, Sam Creasey


This patch series has more macro elimination and some tweaks to the
DMA hooks so that all the wrapper drivers can share the same core
DMA algorithm. This resolves the major discrepancies between the two
core drivers, which relate to code conditional on the REAL_DMA and
PSEUDO_DMA macros.

After all the wrapper drivers agree on the DMA hook api, the core driver
fork gets resolved. NCR5380.c is adopted by atari_scsi and sun3_scsi and
atari_NCR5380.c is then deleted.

Historically, the 5380 drivers suffered from over-use of conditional
compilation, which caused the compile-time configuration space to explode,
leading to core driver code that was practically untestable, unmaintainable
and difficult to reason about. It also prevented driver modules from
sharing object code.

Along with REAL_DMA, REAL_DMA_POLL and PSEUDO_DMA, most of the remaining
macros are also eradicated, such as CONFIG_SCSI_GENERIC_NCR53C400,
SUPPORT_TAGS, DONT_USE_INTR, AUTOPROBE_IRQ and BIOSPARAM.

Also in this patch series, some duplicated documentation is removed and
the PDMA implementation in mac_scsi finally gets fixed.

This patch series has been tested on several platforms. I tested the
dmx3191d and mac_scsi modules on suitable hardware, Michael tested
atari_scsi on an Atari Falcon and Ondrej has tested g_NCR5380 and
g_NCR5380_mmio on various ISA cards.

Changes since v1:
- Patch 4: don't remove MIN_DMA_SIZE macro from wrapper drivers.
- Patch 9: improve commit log entry and add 'Reviewed-by' tag.
- Patch 14: reduce shost->max_lun limit instead of adding MAX_LUN limit.
- Patches 20 and 22: set the default cmd_per_lun to 4.
- For the rest: add 'Reviewed-by' tag.

Changes since v2:
- Patches 20 and 22: revert the default cmd_per_lun to 2, like the v1 patch
series.
- Add patch 23 to fix a theoretical bus reset/autosense issue.

Changes since v3:
- Added 'Tested-by' tags from Ondrej and 'Reviewed-by' tags from Hannes.

---
 Documentation/scsi/g_NCR5380.txt       |   17 
 Documentation/scsi/scsi-parameters.txt |   11 
 drivers/scsi/Kconfig                   |   11 
 drivers/scsi/NCR5380.c                 |  659 ++++----
 drivers/scsi/NCR5380.h                 |  143 -
 drivers/scsi/arm/cumana_1.c            |   25 
 drivers/scsi/arm/oak.c                 |   22 
 drivers/scsi/atari_NCR5380.c           | 2676 ---------------------------------
 drivers/scsi/atari_scsi.c              |  144 -
 drivers/scsi/dmx3191d.c                |   10 
 drivers/scsi/dtc.c                     |   27 
 drivers/scsi/dtc.h                     |    7 
 drivers/scsi/g_NCR5380.c               |  143 -
 drivers/scsi/g_NCR5380.h               |   26 
 drivers/scsi/mac_scsi.c                |  239 +-
 drivers/scsi/pas16.c                   |   27 
 drivers/scsi/pas16.h                   |    5 
 drivers/scsi/sun3_scsi.c               |   47 
 drivers/scsi/t128.c                    |   19 
 drivers/scsi/t128.h                    |    7 
 20 files changed, 634 insertions(+), 3631 deletions(-)

^ permalink raw reply	[flat|nested] 60+ messages in thread

* [PATCH v4 00/23] ncr5380: Eliminate macros, reduce code duplication, fix bugs etc
@ 2016-03-23 10:10 ` Finn Thain
  0 siblings, 0 replies; 60+ messages in thread
From: Finn Thain @ 2016-03-23 10:10 UTC (permalink / raw)
  To: James E.J. Bottomley, Martin K. Petersen, Michael Schmitz,
	linux-m68k, linux-scsi, linux-kernel
  Cc: Ondrej Zary, Sam Creasey


This patch series has more macro elimination and some tweaks to the
DMA hooks so that all the wrapper drivers can share the same core
DMA algorithm. This resolves the major discrepancies between the two
core drivers, which relate to code conditional on the REAL_DMA and
PSEUDO_DMA macros.

After all the wrapper drivers agree on the DMA hook api, the core driver
fork gets resolved. NCR5380.c is adopted by atari_scsi and sun3_scsi and
atari_NCR5380.c is then deleted.

Historically, the 5380 drivers suffered from over-use of conditional
compilation, which caused the compile-time configuration space to explode,
leading to core driver code that was practically untestable, unmaintainable
and difficult to reason about. It also prevented driver modules from
sharing object code.

Along with REAL_DMA, REAL_DMA_POLL and PSEUDO_DMA, most of the remaining
macros are also eradicated, such as CONFIG_SCSI_GENERIC_NCR53C400,
SUPPORT_TAGS, DONT_USE_INTR, AUTOPROBE_IRQ and BIOSPARAM.

Also in this patch series, some duplicated documentation is removed and
the PDMA implementation in mac_scsi finally gets fixed.

This patch series has been tested on several platforms. I tested the
dmx3191d and mac_scsi modules on suitable hardware, Michael tested
atari_scsi on an Atari Falcon and Ondrej has tested g_NCR5380 and
g_NCR5380_mmio on various ISA cards.

Changes since v1:
- Patch 4: don't remove MIN_DMA_SIZE macro from wrapper drivers.
- Patch 9: improve commit log entry and add 'Reviewed-by' tag.
- Patch 14: reduce shost->max_lun limit instead of adding MAX_LUN limit.
- Patches 20 and 22: set the default cmd_per_lun to 4.
- For the rest: add 'Reviewed-by' tag.

Changes since v2:
- Patches 20 and 22: revert the default cmd_per_lun to 2, like the v1 patch
series.
- Add patch 23 to fix a theoretical bus reset/autosense issue.

Changes since v3:
- Added 'Tested-by' tags from Ondrej and 'Reviewed-by' tags from Hannes.

---
 Documentation/scsi/g_NCR5380.txt       |   17 
 Documentation/scsi/scsi-parameters.txt |   11 
 drivers/scsi/Kconfig                   |   11 
 drivers/scsi/NCR5380.c                 |  659 ++++----
 drivers/scsi/NCR5380.h                 |  143 -
 drivers/scsi/arm/cumana_1.c            |   25 
 drivers/scsi/arm/oak.c                 |   22 
 drivers/scsi/atari_NCR5380.c           | 2676 ---------------------------------
 drivers/scsi/atari_scsi.c              |  144 -
 drivers/scsi/dmx3191d.c                |   10 
 drivers/scsi/dtc.c                     |   27 
 drivers/scsi/dtc.h                     |    7 
 drivers/scsi/g_NCR5380.c               |  143 -
 drivers/scsi/g_NCR5380.h               |   26 
 drivers/scsi/mac_scsi.c                |  239 +-
 drivers/scsi/pas16.c                   |   27 
 drivers/scsi/pas16.h                   |    5 
 drivers/scsi/sun3_scsi.c               |   47 
 drivers/scsi/t128.c                    |   19 
 drivers/scsi/t128.h                    |    7 
 20 files changed, 634 insertions(+), 3631 deletions(-)

^ permalink raw reply	[flat|nested] 60+ messages in thread

* [PATCH v4 01/23] g_ncr5380: Remove CONFIG_SCSI_GENERIC_NCR53C400
  2016-03-23 10:10 ` Finn Thain
@ 2016-03-23 10:10   ` Finn Thain
  -1 siblings, 0 replies; 60+ messages in thread
From: Finn Thain @ 2016-03-23 10:10 UTC (permalink / raw)
  To: James E.J. Bottomley, Martin K. Petersen, Michael Schmitz,
	linux-m68k, linux-scsi, linux-kernel
  Cc: Ondrej Zary, Sam Creasey

[-- Attachment #1: g_NCR5380-remove-CONFIG_SCSI_GENERIC_NCR53C400 --]
[-- Type: text/plain, Size: 10437 bytes --]

This change brings a number of improvements: fewer macros, better test
coverage, simpler code and sane Kconfig options. The downside is a small
chance of incompatibility (which seems unavoidable).

CONFIG_SCSI_GENERIC_NCR53C400 exists to enable or inhibit pseudo DMA
transfers when the driver is used with 53C400-compatible cards. Thanks to
Ondrej Zary's patches, PDMA now works which means it can be enabled
unconditionally.

Due to bad design, CONFIG_SCSI_GENERIC_NCR53C400 ties together unrelated
functionality as it sets both PSEUDO_DMA and BIOSPARAM macros. This patch
effectively enables PSEUDO_DMA and disables BIOSPARAM.

The defconfigs and the Kconfig default leave CONFIG_SCSI_GENERIC_NCR53C400
undefined. Red Hat 9 and CentOS 2.1 were the same. This leaves both
PSEUDO_DMA and BIOSPARAM disabled. The effect of this patch should be
better performance from enabling PSEUDO_DMA.

On the other hand, Debian 4 and SLES 10 had CONFIG_SCSI_GENERIC_NCR53C400
enabled, so both PSEUDO_DMA and BIOSPARAM were enabled. This patch might
affect configurations like this by disabling BIOSPARAM. My best guess is
that this could be a problem only in the vanishingly rare case that
1) the CHS values stored in the boot device partition table are wrong and
2) a 5380 card is in use (because PDMA on 53C400 used to be broken).

Signed-off-by: Finn Thain <fthain@telegraphics.com.au>
Reviewed-by: Hannes Reinecke <hare@suse.com>
Tested-by: Ondrej Zary <linux@rainbow-software.org>

---

Here are the distro kernel versions I looked at:

CentOS 2.1:

$ strings kernel-2.4.9-e.40.i686/lib/modules/2.4.9-e.40/kernel/drivers/scsi/g_NCR5380.o | grep extension
NO NCR53C400 driver extensions


Red Hat 7:

$ strings kernel-2.4.18-3.i386/lib/modules/2.4.18-3/kernel/drivers/scsi/g_NCR5380.o | grep extension
NO NCR53C400 driver extensions


Red Hat 9:

$ strings kernel-2.4.20-8.i586/lib/modules/2.4.20-8/kernel/drivers/scsi/g_NCR5380.o | grep extension
NO NCR53C400 driver extensions


Debian 4:

$ strings linux-image-2.6.24-etchnhalf.1-486_2.6.24-6-etchnhalf.9etch3_i386/lib/modules/2.6.24-etchnhalf.1-486/kernel/drivers/scsi/g_NCR5380_mmio.ko | grep extension
NCR53C400 extension version %d
$ strings kernel-image-2.6.8-2-386_2.6.8-13_i386/lib/modules/2.6.8-2-386/kernel/drivers/scsi/g_NCR5380_mmio.ko | grep extension
NCR53C400 extension version %d


SLES 10.2:

$ strings kernel-default-2.6.18.2-34.i586/lib/modules/2.6.18.2-34-default/kernel/drivers/scsi/g_NCR5380_mmio.ko | grep extension
NCR53C400 extension version %d

---
 drivers/scsi/Kconfig     |   11 ------
 drivers/scsi/g_NCR5380.c |   75 ++++++++++++++---------------------------------
 drivers/scsi/g_NCR5380.h |   16 +---------
 3 files changed, 25 insertions(+), 77 deletions(-)

Index: linux/drivers/scsi/Kconfig
===================================================================
--- linux.orig/drivers/scsi/Kconfig	2016-03-23 21:05:16.000000000 +1100
+++ linux/drivers/scsi/Kconfig	2016-03-23 21:09:19.000000000 +1100
@@ -812,17 +812,6 @@ config SCSI_GENERIC_NCR5380_MMIO
 	  To compile this driver as a module, choose M here: the
 	  module will be called g_NCR5380_mmio.
 
-config SCSI_GENERIC_NCR53C400
-	bool "Enable NCR53c400 extensions"
-	depends on SCSI_GENERIC_NCR5380
-	help
-	  This enables certain optimizations for the NCR53c400 SCSI cards.
-	  You might as well try it out.  Note that this driver will only probe
-	  for the Trantor T130B in its default configuration; you might have
-	  to pass a command line option to the kernel at boot time if it does
-	  not detect your card.  See the file
-	  <file:Documentation/scsi/g_NCR5380.txt> for details.
-
 config SCSI_IPS
 	tristate "IBM ServeRAID support"
 	depends on PCI && SCSI
Index: linux/drivers/scsi/g_NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/g_NCR5380.c	2016-03-23 21:05:16.000000000 +1100
+++ linux/drivers/scsi/g_NCR5380.c	2016-03-23 21:09:19.000000000 +1100
@@ -57,10 +57,7 @@
  */
 
 #define AUTOPROBE_IRQ
-
-#ifdef CONFIG_SCSI_GENERIC_NCR53C400
 #define PSEUDO_DMA
-#endif
 
 #include <asm/io.h>
 #include <linux/blkdev.h>
@@ -270,7 +267,7 @@ static int __init generic_NCR5380_detect
 #ifndef SCSI_G_NCR5380_MEM
 	int i;
 	int port_idx = -1;
-	unsigned long region_size = 16;
+	unsigned long region_size;
 #endif
 	static unsigned int __initdata ncr_53c400a_ports[] = {
 		0x280, 0x290, 0x300, 0x310, 0x330, 0x340, 0x348, 0x350, 0
@@ -290,6 +287,7 @@ static int __init generic_NCR5380_detect
 #ifdef SCSI_G_NCR5380_MEM
 	unsigned long base;
 	void __iomem *iomem;
+	resource_size_t iomem_size;
 #endif
 
 	if (ncr_irq)
@@ -353,9 +351,7 @@ static int __init generic_NCR5380_detect
 			flags = FLAG_NO_PSEUDO_DMA;
 			break;
 		case BOARD_NCR53C400:
-#ifdef PSEUDO_DMA
 			flags = FLAG_NO_DMA_FIXUP;
-#endif
 			break;
 		case BOARD_NCR53C400A:
 			flags = FLAG_NO_DMA_FIXUP;
@@ -381,20 +377,22 @@ static int __init generic_NCR5380_detect
 			/* Disable the adapter and look for a free io port */
 			magic_configure(-1, 0, magic);
 
+			region_size = 16;
+
 			if (overrides[current_override].NCR5380_map_name != PORT_AUTO)
 				for (i = 0; ports[i]; i++) {
-					if (!request_region(ports[i],  16, "ncr53c80"))
+					if (!request_region(ports[i], region_size, "ncr53c80"))
 						continue;
 					if (overrides[current_override].NCR5380_map_name == ports[i])
 						break;
-					release_region(ports[i], 16);
+					release_region(ports[i], region_size);
 			} else
 				for (i = 0; ports[i]; i++) {
-					if (!request_region(ports[i],  16, "ncr53c80"))
+					if (!request_region(ports[i], region_size, "ncr53c80"))
 						continue;
 					if (inb(ports[i]) == 0xff)
 						break;
-					release_region(ports[i], 16);
+					release_region(ports[i], region_size);
 				}
 			if (ports[i]) {
 				/* At this point we have our region reserved */
@@ -410,17 +408,19 @@ static int __init generic_NCR5380_detect
 		else
 		{
 			/* Not a 53C400A style setup - just grab */
-			if(!(request_region(overrides[current_override].NCR5380_map_name, NCR5380_region_size, "ncr5380")))
+			region_size = 8;
+			if (!request_region(overrides[current_override].NCR5380_map_name,
+			                    region_size, "ncr5380"))
 				continue;
-			region_size = NCR5380_region_size;
 		}
 #else
 		base = overrides[current_override].NCR5380_map_name;
-		if (!request_mem_region(base, NCR5380_region_size, "ncr5380"))
+		iomem_size = NCR53C400_region_size;
+		if (!request_mem_region(base, iomem_size, "ncr5380"))
 			continue;
-		iomem = ioremap(base, NCR5380_region_size);
+		iomem = ioremap(base, iomem_size);
 		if (!iomem) {
-			release_mem_region(base, NCR5380_region_size);
+			release_mem_region(base, iomem_size);
 			continue;
 		}
 #endif
@@ -458,6 +458,7 @@ static int __init generic_NCR5380_detect
 #else
 		instance->base = overrides[current_override].NCR5380_map_name;
 		hostdata->iomem = iomem;
+		hostdata->iomem_size = iomem_size;
 		switch (overrides[current_override].board) {
 		case BOARD_NCR53C400:
 			hostdata->c400_ctl_status = 0x100;
@@ -524,7 +525,7 @@ out_release:
 	release_region(overrides[current_override].NCR5380_map_name, region_size);
 #else
 	iounmap(iomem);
-	release_mem_region(base, NCR5380_region_size);
+	release_mem_region(base, iomem_size);
 #endif
 	return count;
 }
@@ -546,42 +547,15 @@ static int generic_NCR5380_release_resou
 #ifndef SCSI_G_NCR5380_MEM
 	release_region(instance->io_port, instance->n_io_port);
 #else
-	iounmap(((struct NCR5380_hostdata *)instance->hostdata)->iomem);
-	release_mem_region(instance->base, NCR5380_region_size);
-#endif
-	return 0;
-}
+	{
+		struct NCR5380_hostdata *hostdata = shost_priv(instance);
 
-#ifdef BIOSPARAM
-/**
- *	generic_NCR5380_biosparam
- *	@disk: disk to compute geometry for
- *	@dev: device identifier for this disk
- *	@ip: sizes to fill in
- *
- *	Generates a BIOS / DOS compatible H-C-S mapping for the specified 
- *	device / size.
- * 
- * 	XXX Most SCSI boards use this mapping, I could be incorrect.  Someone
- *	using hard disks on a trantor should verify that this mapping
- *	corresponds to that used by the BIOS / ASPI driver by running the linux
- *	fdisk program and matching the H_C_S coordinates to what DOS uses.
- *
- *	Locks: none
- */
-
-static int
-generic_NCR5380_biosparam(struct scsi_device *sdev, struct block_device *bdev,
-			  sector_t capacity, int *ip)
-{
-	ip[0] = 64;
-	ip[1] = 32;
-	ip[2] = capacity >> 11;
+		iounmap(hostdata->iomem);
+		release_mem_region(instance->base, hostdata->iomem_size);
+	}
+#endif
 	return 0;
 }
-#endif
-
-#ifdef PSEUDO_DMA
 
 /**
  *	NCR5380_pread		-	pseudo DMA read
@@ -756,8 +730,6 @@ static int generic_NCR5380_dma_xfer_len(
 	return transfersize;
 }
 
-#endif /* PSEUDO_DMA */
-
 /*
  *	Include the NCR5380 core code that we build our driver around	
  */
@@ -773,7 +745,6 @@ static struct scsi_host_template driver_
 	.queuecommand		= generic_NCR5380_queue_command,
 	.eh_abort_handler	= generic_NCR5380_abort,
 	.eh_bus_reset_handler	= generic_NCR5380_bus_reset,
-	.bios_param		= NCR5380_BIOSPARAM,
 	.can_queue		= 16,
 	.this_id		= 7,
 	.sg_tablesize		= SG_ALL,
Index: linux/drivers/scsi/g_NCR5380.h
===================================================================
--- linux.orig/drivers/scsi/g_NCR5380.h	2016-03-23 21:05:16.000000000 +1100
+++ linux/drivers/scsi/g_NCR5380.h	2016-03-23 21:09:19.000000000 +1100
@@ -14,13 +14,6 @@
 #ifndef GENERIC_NCR5380_H
 #define GENERIC_NCR5380_H
 
-#ifdef CONFIG_SCSI_GENERIC_NCR53C400
-#define BIOSPARAM
-#define NCR5380_BIOSPARAM generic_NCR5380_biosparam
-#else
-#define NCR5380_BIOSPARAM NULL
-#endif
-
 #define __STRVAL(x) #x
 #define STRVAL(x) __STRVAL(x)
 
@@ -30,12 +23,6 @@
 #define NCR5380_map_type int
 #define NCR5380_map_name port
 
-#ifdef CONFIG_SCSI_GENERIC_NCR53C400
-#define NCR5380_region_size 16
-#else
-#define NCR5380_region_size 8
-#endif
-
 #define NCR5380_read(reg) \
 	inb(instance->io_port + (reg))
 #define NCR5380_write(reg, value) \
@@ -55,7 +42,7 @@
 #define NCR5380_map_name base
 #define NCR53C400_mem_base 0x3880
 #define NCR53C400_host_buffer 0x3900
-#define NCR5380_region_size 0x3a00
+#define NCR53C400_region_size 0x3a00
 
 #define NCR5380_read(reg) \
 	readb(((struct NCR5380_hostdata *)shost_priv(instance))->iomem + \
@@ -66,6 +53,7 @@
 
 #define NCR5380_implementation_fields \
 	void __iomem *iomem; \
+	resource_size_t iomem_size; \
 	int c400_ctl_status; \
 	int c400_blk_cnt; \
 	int c400_host_buf;

^ permalink raw reply	[flat|nested] 60+ messages in thread

* [PATCH v4 01/23] g_ncr5380: Remove CONFIG_SCSI_GENERIC_NCR53C400
@ 2016-03-23 10:10   ` Finn Thain
  0 siblings, 0 replies; 60+ messages in thread
From: Finn Thain @ 2016-03-23 10:10 UTC (permalink / raw)
  To: James E.J. Bottomley, Martin K. Petersen, Michael Schmitz,
	linux-m68k, linux-scsi, linux-kernel
  Cc: Ondrej Zary, Sam Creasey

[-- Attachment #1: g_NCR5380-remove-CONFIG_SCSI_GENERIC_NCR53C400 --]
[-- Type: text/plain, Size: 10437 bytes --]

This change brings a number of improvements: fewer macros, better test
coverage, simpler code and sane Kconfig options. The downside is a small
chance of incompatibility (which seems unavoidable).

CONFIG_SCSI_GENERIC_NCR53C400 exists to enable or inhibit pseudo DMA
transfers when the driver is used with 53C400-compatible cards. Thanks to
Ondrej Zary's patches, PDMA now works which means it can be enabled
unconditionally.

Due to bad design, CONFIG_SCSI_GENERIC_NCR53C400 ties together unrelated
functionality as it sets both PSEUDO_DMA and BIOSPARAM macros. This patch
effectively enables PSEUDO_DMA and disables BIOSPARAM.

The defconfigs and the Kconfig default leave CONFIG_SCSI_GENERIC_NCR53C400
undefined. Red Hat 9 and CentOS 2.1 were the same. This leaves both
PSEUDO_DMA and BIOSPARAM disabled. The effect of this patch should be
better performance from enabling PSEUDO_DMA.

On the other hand, Debian 4 and SLES 10 had CONFIG_SCSI_GENERIC_NCR53C400
enabled, so both PSEUDO_DMA and BIOSPARAM were enabled. This patch might
affect configurations like this by disabling BIOSPARAM. My best guess is
that this could be a problem only in the vanishingly rare case that
1) the CHS values stored in the boot device partition table are wrong and
2) a 5380 card is in use (because PDMA on 53C400 used to be broken).

Signed-off-by: Finn Thain <fthain@telegraphics.com.au>
Reviewed-by: Hannes Reinecke <hare@suse.com>
Tested-by: Ondrej Zary <linux@rainbow-software.org>

---

Here are the distro kernel versions I looked at:

CentOS 2.1:

$ strings kernel-2.4.9-e.40.i686/lib/modules/2.4.9-e.40/kernel/drivers/scsi/g_NCR5380.o | grep extension
NO NCR53C400 driver extensions


Red Hat 7:

$ strings kernel-2.4.18-3.i386/lib/modules/2.4.18-3/kernel/drivers/scsi/g_NCR5380.o | grep extension
NO NCR53C400 driver extensions


Red Hat 9:

$ strings kernel-2.4.20-8.i586/lib/modules/2.4.20-8/kernel/drivers/scsi/g_NCR5380.o | grep extension
NO NCR53C400 driver extensions


Debian 4:

$ strings linux-image-2.6.24-etchnhalf.1-486_2.6.24-6-etchnhalf.9etch3_i386/lib/modules/2.6.24-etchnhalf.1-486/kernel/drivers/scsi/g_NCR5380_mmio.ko | grep extension
NCR53C400 extension version %d
$ strings kernel-image-2.6.8-2-386_2.6.8-13_i386/lib/modules/2.6.8-2-386/kernel/drivers/scsi/g_NCR5380_mmio.ko | grep extension
NCR53C400 extension version %d


SLES 10.2:

$ strings kernel-default-2.6.18.2-34.i586/lib/modules/2.6.18.2-34-default/kernel/drivers/scsi/g_NCR5380_mmio.ko | grep extension
NCR53C400 extension version %d

---
 drivers/scsi/Kconfig     |   11 ------
 drivers/scsi/g_NCR5380.c |   75 ++++++++++++++---------------------------------
 drivers/scsi/g_NCR5380.h |   16 +---------
 3 files changed, 25 insertions(+), 77 deletions(-)

Index: linux/drivers/scsi/Kconfig
===================================================================
--- linux.orig/drivers/scsi/Kconfig	2016-03-23 21:05:16.000000000 +1100
+++ linux/drivers/scsi/Kconfig	2016-03-23 21:09:19.000000000 +1100
@@ -812,17 +812,6 @@ config SCSI_GENERIC_NCR5380_MMIO
 	  To compile this driver as a module, choose M here: the
 	  module will be called g_NCR5380_mmio.
 
-config SCSI_GENERIC_NCR53C400
-	bool "Enable NCR53c400 extensions"
-	depends on SCSI_GENERIC_NCR5380
-	help
-	  This enables certain optimizations for the NCR53c400 SCSI cards.
-	  You might as well try it out.  Note that this driver will only probe
-	  for the Trantor T130B in its default configuration; you might have
-	  to pass a command line option to the kernel at boot time if it does
-	  not detect your card.  See the file
-	  <file:Documentation/scsi/g_NCR5380.txt> for details.
-
 config SCSI_IPS
 	tristate "IBM ServeRAID support"
 	depends on PCI && SCSI
Index: linux/drivers/scsi/g_NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/g_NCR5380.c	2016-03-23 21:05:16.000000000 +1100
+++ linux/drivers/scsi/g_NCR5380.c	2016-03-23 21:09:19.000000000 +1100
@@ -57,10 +57,7 @@
  */
 
 #define AUTOPROBE_IRQ
-
-#ifdef CONFIG_SCSI_GENERIC_NCR53C400
 #define PSEUDO_DMA
-#endif
 
 #include <asm/io.h>
 #include <linux/blkdev.h>
@@ -270,7 +267,7 @@ static int __init generic_NCR5380_detect
 #ifndef SCSI_G_NCR5380_MEM
 	int i;
 	int port_idx = -1;
-	unsigned long region_size = 16;
+	unsigned long region_size;
 #endif
 	static unsigned int __initdata ncr_53c400a_ports[] = {
 		0x280, 0x290, 0x300, 0x310, 0x330, 0x340, 0x348, 0x350, 0
@@ -290,6 +287,7 @@ static int __init generic_NCR5380_detect
 #ifdef SCSI_G_NCR5380_MEM
 	unsigned long base;
 	void __iomem *iomem;
+	resource_size_t iomem_size;
 #endif
 
 	if (ncr_irq)
@@ -353,9 +351,7 @@ static int __init generic_NCR5380_detect
 			flags = FLAG_NO_PSEUDO_DMA;
 			break;
 		case BOARD_NCR53C400:
-#ifdef PSEUDO_DMA
 			flags = FLAG_NO_DMA_FIXUP;
-#endif
 			break;
 		case BOARD_NCR53C400A:
 			flags = FLAG_NO_DMA_FIXUP;
@@ -381,20 +377,22 @@ static int __init generic_NCR5380_detect
 			/* Disable the adapter and look for a free io port */
 			magic_configure(-1, 0, magic);
 
+			region_size = 16;
+
 			if (overrides[current_override].NCR5380_map_name != PORT_AUTO)
 				for (i = 0; ports[i]; i++) {
-					if (!request_region(ports[i],  16, "ncr53c80"))
+					if (!request_region(ports[i], region_size, "ncr53c80"))
 						continue;
 					if (overrides[current_override].NCR5380_map_name == ports[i])
 						break;
-					release_region(ports[i], 16);
+					release_region(ports[i], region_size);
 			} else
 				for (i = 0; ports[i]; i++) {
-					if (!request_region(ports[i],  16, "ncr53c80"))
+					if (!request_region(ports[i], region_size, "ncr53c80"))
 						continue;
 					if (inb(ports[i]) == 0xff)
 						break;
-					release_region(ports[i], 16);
+					release_region(ports[i], region_size);
 				}
 			if (ports[i]) {
 				/* At this point we have our region reserved */
@@ -410,17 +408,19 @@ static int __init generic_NCR5380_detect
 		else
 		{
 			/* Not a 53C400A style setup - just grab */
-			if(!(request_region(overrides[current_override].NCR5380_map_name, NCR5380_region_size, "ncr5380")))
+			region_size = 8;
+			if (!request_region(overrides[current_override].NCR5380_map_name,
+			                    region_size, "ncr5380"))
 				continue;
-			region_size = NCR5380_region_size;
 		}
 #else
 		base = overrides[current_override].NCR5380_map_name;
-		if (!request_mem_region(base, NCR5380_region_size, "ncr5380"))
+		iomem_size = NCR53C400_region_size;
+		if (!request_mem_region(base, iomem_size, "ncr5380"))
 			continue;
-		iomem = ioremap(base, NCR5380_region_size);
+		iomem = ioremap(base, iomem_size);
 		if (!iomem) {
-			release_mem_region(base, NCR5380_region_size);
+			release_mem_region(base, iomem_size);
 			continue;
 		}
 #endif
@@ -458,6 +458,7 @@ static int __init generic_NCR5380_detect
 #else
 		instance->base = overrides[current_override].NCR5380_map_name;
 		hostdata->iomem = iomem;
+		hostdata->iomem_size = iomem_size;
 		switch (overrides[current_override].board) {
 		case BOARD_NCR53C400:
 			hostdata->c400_ctl_status = 0x100;
@@ -524,7 +525,7 @@ out_release:
 	release_region(overrides[current_override].NCR5380_map_name, region_size);
 #else
 	iounmap(iomem);
-	release_mem_region(base, NCR5380_region_size);
+	release_mem_region(base, iomem_size);
 #endif
 	return count;
 }
@@ -546,42 +547,15 @@ static int generic_NCR5380_release_resou
 #ifndef SCSI_G_NCR5380_MEM
 	release_region(instance->io_port, instance->n_io_port);
 #else
-	iounmap(((struct NCR5380_hostdata *)instance->hostdata)->iomem);
-	release_mem_region(instance->base, NCR5380_region_size);
-#endif
-	return 0;
-}
+	{
+		struct NCR5380_hostdata *hostdata = shost_priv(instance);
 
-#ifdef BIOSPARAM
-/**
- *	generic_NCR5380_biosparam
- *	@disk: disk to compute geometry for
- *	@dev: device identifier for this disk
- *	@ip: sizes to fill in
- *
- *	Generates a BIOS / DOS compatible H-C-S mapping for the specified 
- *	device / size.
- * 
- * 	XXX Most SCSI boards use this mapping, I could be incorrect.  Someone
- *	using hard disks on a trantor should verify that this mapping
- *	corresponds to that used by the BIOS / ASPI driver by running the linux
- *	fdisk program and matching the H_C_S coordinates to what DOS uses.
- *
- *	Locks: none
- */
-
-static int
-generic_NCR5380_biosparam(struct scsi_device *sdev, struct block_device *bdev,
-			  sector_t capacity, int *ip)
-{
-	ip[0] = 64;
-	ip[1] = 32;
-	ip[2] = capacity >> 11;
+		iounmap(hostdata->iomem);
+		release_mem_region(instance->base, hostdata->iomem_size);
+	}
+#endif
 	return 0;
 }
-#endif
-
-#ifdef PSEUDO_DMA
 
 /**
  *	NCR5380_pread		-	pseudo DMA read
@@ -756,8 +730,6 @@ static int generic_NCR5380_dma_xfer_len(
 	return transfersize;
 }
 
-#endif /* PSEUDO_DMA */
-
 /*
  *	Include the NCR5380 core code that we build our driver around	
  */
@@ -773,7 +745,6 @@ static struct scsi_host_template driver_
 	.queuecommand		= generic_NCR5380_queue_command,
 	.eh_abort_handler	= generic_NCR5380_abort,
 	.eh_bus_reset_handler	= generic_NCR5380_bus_reset,
-	.bios_param		= NCR5380_BIOSPARAM,
 	.can_queue		= 16,
 	.this_id		= 7,
 	.sg_tablesize		= SG_ALL,
Index: linux/drivers/scsi/g_NCR5380.h
===================================================================
--- linux.orig/drivers/scsi/g_NCR5380.h	2016-03-23 21:05:16.000000000 +1100
+++ linux/drivers/scsi/g_NCR5380.h	2016-03-23 21:09:19.000000000 +1100
@@ -14,13 +14,6 @@
 #ifndef GENERIC_NCR5380_H
 #define GENERIC_NCR5380_H
 
-#ifdef CONFIG_SCSI_GENERIC_NCR53C400
-#define BIOSPARAM
-#define NCR5380_BIOSPARAM generic_NCR5380_biosparam
-#else
-#define NCR5380_BIOSPARAM NULL
-#endif
-
 #define __STRVAL(x) #x
 #define STRVAL(x) __STRVAL(x)
 
@@ -30,12 +23,6 @@
 #define NCR5380_map_type int
 #define NCR5380_map_name port
 
-#ifdef CONFIG_SCSI_GENERIC_NCR53C400
-#define NCR5380_region_size 16
-#else
-#define NCR5380_region_size 8
-#endif
-
 #define NCR5380_read(reg) \
 	inb(instance->io_port + (reg))
 #define NCR5380_write(reg, value) \
@@ -55,7 +42,7 @@
 #define NCR5380_map_name base
 #define NCR53C400_mem_base 0x3880
 #define NCR53C400_host_buffer 0x3900
-#define NCR5380_region_size 0x3a00
+#define NCR53C400_region_size 0x3a00
 
 #define NCR5380_read(reg) \
 	readb(((struct NCR5380_hostdata *)shost_priv(instance))->iomem + \
@@ -66,6 +53,7 @@
 
 #define NCR5380_implementation_fields \
 	void __iomem *iomem; \
+	resource_size_t iomem_size; \
 	int c400_ctl_status; \
 	int c400_blk_cnt; \
 	int c400_host_buf;

^ permalink raw reply	[flat|nested] 60+ messages in thread

* [PATCH v4 02/23] ncr5380: Remove FLAG_NO_PSEUDO_DMA where possible
  2016-03-23 10:10 ` Finn Thain
@ 2016-03-23 10:10   ` Finn Thain
  -1 siblings, 0 replies; 60+ messages in thread
From: Finn Thain @ 2016-03-23 10:10 UTC (permalink / raw)
  To: James E.J. Bottomley, Martin K. Petersen, Michael Schmitz,
	linux-m68k, linux-scsi, linux-kernel
  Cc: Ondrej Zary, Sam Creasey

[-- Attachment #1: ncr5380-FLAG_NO_PSEUDO_DMA --]
[-- Type: text/plain, Size: 4220 bytes --]

Drivers that define PSEUDO_DMA also define NCR5380_dma_xfer_len.
The core driver must call NCR5380_dma_xfer_len which means
FLAG_NO_PSEUDO_DMA can be eradicated from the core driver.

dmx3191d doesn't define PSEUDO_DMA and has no use for FLAG_NO_PSEUDO_DMA,
so remove it there also.

Signed-off-by: Finn Thain <fthain@telegraphics.com.au>
Reviewed-by: Hannes Reinecke <hare@suse.com>
Tested-by: Michael Schmitz <schmitzmic@gmail.com>
Tested-by: Ondrej Zary <linux@rainbow-software.org>

---
 drivers/scsi/NCR5380.c   |    3 +--
 drivers/scsi/dmx3191d.c  |    2 +-
 drivers/scsi/g_NCR5380.c |    7 ++++++-
 drivers/scsi/g_NCR5380.h |    2 +-
 drivers/scsi/mac_scsi.c  |   15 ++++++++++++++-
 5 files changed, 23 insertions(+), 6 deletions(-)

Index: linux/drivers/scsi/dmx3191d.c
===================================================================
--- linux.orig/drivers/scsi/dmx3191d.c	2016-03-23 21:05:16.000000000 +1100
+++ linux/drivers/scsi/dmx3191d.c	2016-03-23 21:09:20.000000000 +1100
@@ -93,7 +93,7 @@ static int dmx3191d_probe_one(struct pci
 	 */
 	shost->irq = NO_IRQ;
 
-	error = NCR5380_init(shost, FLAG_NO_PSEUDO_DMA);
+	error = NCR5380_init(shost, 0);
 	if (error)
 		goto out_host_put;
 
Index: linux/drivers/scsi/mac_scsi.c
===================================================================
--- linux.orig/drivers/scsi/mac_scsi.c	2016-03-23 21:05:16.000000000 +1100
+++ linux/drivers/scsi/mac_scsi.c	2016-03-23 21:09:20.000000000 +1100
@@ -37,7 +37,9 @@
 
 #define NCR5380_pread                   macscsi_pread
 #define NCR5380_pwrite                  macscsi_pwrite
-#define NCR5380_dma_xfer_len(instance, cmd, phase)	(cmd->transfersize)
+
+#define NCR5380_dma_xfer_len(instance, cmd, phase) \
+        macscsi_dma_xfer_len(instance, cmd)
 
 #define NCR5380_intr                    macscsi_intr
 #define NCR5380_queue_command           macscsi_queue_command
@@ -303,6 +305,17 @@ static int macscsi_pwrite(struct Scsi_Ho
 }
 #endif
 
+static int macscsi_dma_xfer_len(struct Scsi_Host *instance,
+                                struct scsi_cmnd *cmd)
+{
+	struct NCR5380_hostdata *hostdata = shost_priv(instance);
+
+	if (hostdata->flags & FLAG_NO_PSEUDO_DMA)
+		return 0;
+
+	return cmd->transfersize;
+}
+
 #include "NCR5380.c"
 
 #define DRV_MODULE_NAME         "mac_scsi"
Index: linux/drivers/scsi/g_NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/g_NCR5380.c	2016-03-23 21:09:19.000000000 +1100
+++ linux/drivers/scsi/g_NCR5380.c	2016-03-23 21:09:20.000000000 +1100
@@ -712,10 +712,15 @@ static inline int NCR5380_pwrite(struct
 	return 0;
 }
 
-static int generic_NCR5380_dma_xfer_len(struct scsi_cmnd *cmd)
+static int generic_NCR5380_dma_xfer_len(struct Scsi_Host *instance,
+                                        struct scsi_cmnd *cmd)
 {
+	struct NCR5380_hostdata *hostdata = shost_priv(instance);
 	int transfersize = cmd->transfersize;
 
+	if (hostdata->flags & FLAG_NO_PSEUDO_DMA)
+		return 0;
+
 	/* Limit transfers to 32K, for xx400 & xx406
 	 * pseudoDMA that transfers in 128 bytes blocks.
 	 */
Index: linux/drivers/scsi/NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/NCR5380.c	2016-03-23 21:09:19.000000000 +1100
+++ linux/drivers/scsi/NCR5380.c	2016-03-23 21:09:20.000000000 +1100
@@ -1833,8 +1833,7 @@ static void NCR5380_information_transfer
 
 #if defined(PSEUDO_DMA) || defined(REAL_DMA_POLL)
 				transfersize = 0;
-				if (!cmd->device->borken &&
-				    !(hostdata->flags & FLAG_NO_PSEUDO_DMA))
+				if (!cmd->device->borken)
 					transfersize = NCR5380_dma_xfer_len(instance, cmd, phase);
 
 				if (transfersize) {
Index: linux/drivers/scsi/g_NCR5380.h
===================================================================
--- linux.orig/drivers/scsi/g_NCR5380.h	2016-03-23 21:09:19.000000000 +1100
+++ linux/drivers/scsi/g_NCR5380.h	2016-03-23 21:09:20.000000000 +1100
@@ -61,7 +61,7 @@
 #endif
 
 #define NCR5380_dma_xfer_len(instance, cmd, phase) \
-        generic_NCR5380_dma_xfer_len(cmd)
+        generic_NCR5380_dma_xfer_len(instance, cmd)
 
 #define NCR5380_intr generic_NCR5380_intr
 #define NCR5380_queue_command generic_NCR5380_queue_command

^ permalink raw reply	[flat|nested] 60+ messages in thread

* [PATCH v4 02/23] ncr5380: Remove FLAG_NO_PSEUDO_DMA where possible
@ 2016-03-23 10:10   ` Finn Thain
  0 siblings, 0 replies; 60+ messages in thread
From: Finn Thain @ 2016-03-23 10:10 UTC (permalink / raw)
  To: James E.J. Bottomley, Martin K. Petersen, Michael Schmitz,
	linux-m68k, linux-scsi, linux-kernel
  Cc: Ondrej Zary, Sam Creasey

[-- Attachment #1: ncr5380-FLAG_NO_PSEUDO_DMA --]
[-- Type: text/plain, Size: 4220 bytes --]

Drivers that define PSEUDO_DMA also define NCR5380_dma_xfer_len.
The core driver must call NCR5380_dma_xfer_len which means
FLAG_NO_PSEUDO_DMA can be eradicated from the core driver.

dmx3191d doesn't define PSEUDO_DMA and has no use for FLAG_NO_PSEUDO_DMA,
so remove it there also.

Signed-off-by: Finn Thain <fthain@telegraphics.com.au>
Reviewed-by: Hannes Reinecke <hare@suse.com>
Tested-by: Michael Schmitz <schmitzmic@gmail.com>
Tested-by: Ondrej Zary <linux@rainbow-software.org>

---
 drivers/scsi/NCR5380.c   |    3 +--
 drivers/scsi/dmx3191d.c  |    2 +-
 drivers/scsi/g_NCR5380.c |    7 ++++++-
 drivers/scsi/g_NCR5380.h |    2 +-
 drivers/scsi/mac_scsi.c  |   15 ++++++++++++++-
 5 files changed, 23 insertions(+), 6 deletions(-)

Index: linux/drivers/scsi/dmx3191d.c
===================================================================
--- linux.orig/drivers/scsi/dmx3191d.c	2016-03-23 21:05:16.000000000 +1100
+++ linux/drivers/scsi/dmx3191d.c	2016-03-23 21:09:20.000000000 +1100
@@ -93,7 +93,7 @@ static int dmx3191d_probe_one(struct pci
 	 */
 	shost->irq = NO_IRQ;
 
-	error = NCR5380_init(shost, FLAG_NO_PSEUDO_DMA);
+	error = NCR5380_init(shost, 0);
 	if (error)
 		goto out_host_put;
 
Index: linux/drivers/scsi/mac_scsi.c
===================================================================
--- linux.orig/drivers/scsi/mac_scsi.c	2016-03-23 21:05:16.000000000 +1100
+++ linux/drivers/scsi/mac_scsi.c	2016-03-23 21:09:20.000000000 +1100
@@ -37,7 +37,9 @@
 
 #define NCR5380_pread                   macscsi_pread
 #define NCR5380_pwrite                  macscsi_pwrite
-#define NCR5380_dma_xfer_len(instance, cmd, phase)	(cmd->transfersize)
+
+#define NCR5380_dma_xfer_len(instance, cmd, phase) \
+        macscsi_dma_xfer_len(instance, cmd)
 
 #define NCR5380_intr                    macscsi_intr
 #define NCR5380_queue_command           macscsi_queue_command
@@ -303,6 +305,17 @@ static int macscsi_pwrite(struct Scsi_Ho
 }
 #endif
 
+static int macscsi_dma_xfer_len(struct Scsi_Host *instance,
+                                struct scsi_cmnd *cmd)
+{
+	struct NCR5380_hostdata *hostdata = shost_priv(instance);
+
+	if (hostdata->flags & FLAG_NO_PSEUDO_DMA)
+		return 0;
+
+	return cmd->transfersize;
+}
+
 #include "NCR5380.c"
 
 #define DRV_MODULE_NAME         "mac_scsi"
Index: linux/drivers/scsi/g_NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/g_NCR5380.c	2016-03-23 21:09:19.000000000 +1100
+++ linux/drivers/scsi/g_NCR5380.c	2016-03-23 21:09:20.000000000 +1100
@@ -712,10 +712,15 @@ static inline int NCR5380_pwrite(struct
 	return 0;
 }
 
-static int generic_NCR5380_dma_xfer_len(struct scsi_cmnd *cmd)
+static int generic_NCR5380_dma_xfer_len(struct Scsi_Host *instance,
+                                        struct scsi_cmnd *cmd)
 {
+	struct NCR5380_hostdata *hostdata = shost_priv(instance);
 	int transfersize = cmd->transfersize;
 
+	if (hostdata->flags & FLAG_NO_PSEUDO_DMA)
+		return 0;
+
 	/* Limit transfers to 32K, for xx400 & xx406
 	 * pseudoDMA that transfers in 128 bytes blocks.
 	 */
Index: linux/drivers/scsi/NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/NCR5380.c	2016-03-23 21:09:19.000000000 +1100
+++ linux/drivers/scsi/NCR5380.c	2016-03-23 21:09:20.000000000 +1100
@@ -1833,8 +1833,7 @@ static void NCR5380_information_transfer
 
 #if defined(PSEUDO_DMA) || defined(REAL_DMA_POLL)
 				transfersize = 0;
-				if (!cmd->device->borken &&
-				    !(hostdata->flags & FLAG_NO_PSEUDO_DMA))
+				if (!cmd->device->borken)
 					transfersize = NCR5380_dma_xfer_len(instance, cmd, phase);
 
 				if (transfersize) {
Index: linux/drivers/scsi/g_NCR5380.h
===================================================================
--- linux.orig/drivers/scsi/g_NCR5380.h	2016-03-23 21:09:19.000000000 +1100
+++ linux/drivers/scsi/g_NCR5380.h	2016-03-23 21:09:20.000000000 +1100
@@ -61,7 +61,7 @@
 #endif
 
 #define NCR5380_dma_xfer_len(instance, cmd, phase) \
-        generic_NCR5380_dma_xfer_len(cmd)
+        generic_NCR5380_dma_xfer_len(instance, cmd)
 
 #define NCR5380_intr generic_NCR5380_intr
 #define NCR5380_queue_command generic_NCR5380_queue_command

^ permalink raw reply	[flat|nested] 60+ messages in thread

* [PATCH v4 03/23] ncr5380: Remove REAL_DMA and REAL_DMA_POLL macros
  2016-03-23 10:10 ` Finn Thain
@ 2016-03-23 10:10   ` Finn Thain
  -1 siblings, 0 replies; 60+ messages in thread
From: Finn Thain @ 2016-03-23 10:10 UTC (permalink / raw)
  To: James E.J. Bottomley, Martin K. Petersen, Michael Schmitz,
	linux-m68k, linux-scsi, linux-kernel
  Cc: Ondrej Zary, Sam Creasey

[-- Attachment #1: ncr5380-remove-REAL_DMA-macro --]
[-- Type: text/plain, Size: 30384 bytes --]

For the NCR5380.c core driver, these macros are never used.
If REAL_DMA were to be defined, compilation would fail.

For the atari_NCR5380.c core driver, REAL_DMA is always defined.

Hence these macros are pointless.

Signed-off-by: Finn Thain <fthain@telegraphics.com.au>
Reviewed-by: Hannes Reinecke <hare@suse.com>
Tested-by: Michael Schmitz <schmitzmic@gmail.com>
Tested-by: Ondrej Zary <linux@rainbow-software.org>

---
 drivers/scsi/NCR5380.c       |  218 +------------------------------------------
 drivers/scsi/NCR5380.h       |  112 ----------------------
 drivers/scsi/atari_NCR5380.c |   62 +-----------
 drivers/scsi/atari_scsi.c    |   32 ------
 drivers/scsi/sun3_scsi.c     |   13 --
 5 files changed, 22 insertions(+), 415 deletions(-)

Index: linux/drivers/scsi/NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/NCR5380.c	2016-03-23 21:09:20.000000000 +1100
+++ linux/drivers/scsi/NCR5380.c	2016-03-23 21:09:22.000000000 +1100
@@ -35,18 +35,10 @@
  * code so that everything does the same thing that's done at the
  * end of a pseudo-DMA read operation.
  *
- * 2.  Fix REAL_DMA (interrupt driven, polled works fine) -
- * basically, transfer size needs to be reduced by one
- * and the last byte read as is done with PSEUDO_DMA.
- *
  * 4.  Test SCSI-II tagged queueing (I have no devices which support
  * tagged queueing)
  */
 
-#ifndef notyet
-#undef REAL_DMA
-#endif
-
 #ifdef BOARD_REQUIRES_NO_DELAY
 #define io_recovery_delay(x)
 #else
@@ -131,12 +123,6 @@
  *
  * PSEUDO_DMA - if defined, PSEUDO DMA is used during the data transfer phases.
  *
- * REAL_DMA - if defined, REAL DMA is used during the data transfer phases.
- *
- * REAL_DMA_POLL - if defined, REAL DMA is used but the driver doesn't
- * rely on phase mismatch and EOP interrupts to determine end
- * of phase.
- *
  * These macros MUST be defined :
  *
  * NCR5380_read(register)  - read from the specified register
@@ -147,15 +133,9 @@
  * specific implementation of the NCR5380
  *
  * Either real DMA *or* pseudo DMA may be implemented
- * REAL functions :
- * NCR5380_REAL_DMA should be defined if real DMA is to be used.
  * Note that the DMA setup functions should return the number of bytes
  * that they were able to program the controller for.
  *
- * Also note that generic i386/PC versions of these macros are
- * available as NCR5380_i386_dma_write_setup,
- * NCR5380_i386_dma_read_setup, and NCR5380_i386_dma_residual.
- *
  * NCR5380_dma_write_setup(instance, src, count) - initialize
  * NCR5380_dma_read_setup(instance, dst, count) - initialize
  * NCR5380_dma_residual(instance); - residual count
@@ -486,12 +466,6 @@ static void prepare_info(struct Scsi_Hos
 #ifdef DIFFERENTIAL
 	         "DIFFERENTIAL "
 #endif
-#ifdef REAL_DMA
-	         "REAL_DMA "
-#endif
-#ifdef REAL_DMA_POLL
-	         "REAL_DMA_POLL "
-#endif
 #ifdef PARITY
 	         "PARITY "
 #endif
@@ -551,9 +525,8 @@ static int NCR5380_init(struct Scsi_Host
 			hostdata->id_higher_mask |= i;
 	for (i = 0; i < 8; ++i)
 		hostdata->busy[i] = 0;
-#ifdef REAL_DMA
-	hostdata->dmalen = 0;
-#endif
+	hostdata->dma_len = 0;
+
 	spin_lock_init(&hostdata->lock);
 	hostdata->connected = NULL;
 	hostdata->sensing = NULL;
@@ -850,11 +823,7 @@ static void NCR5380_main(struct work_str
 				requeue_cmd(instance, cmd);
 			}
 		}
-		if (hostdata->connected
-#ifdef REAL_DMA
-		    && !hostdata->dmalen
-#endif
-		    ) {
+		if (hostdata->connected && !hostdata->dma_len) {
 			dsprintk(NDEBUG_MAIN, instance, "main: performing information transfer\n");
 			NCR5380_information_transfer(instance);
 			done = 0;
@@ -919,34 +888,6 @@ static irqreturn_t NCR5380_intr(int irq,
 		dsprintk(NDEBUG_INTR, instance, "IRQ %d, BASR 0x%02x, SR 0x%02x, MR 0x%02x\n",
 		         irq, basr, sr, mr);
 
-#if defined(REAL_DMA)
-		if ((mr & MR_DMA_MODE) || (mr & MR_MONITOR_BSY)) {
-			/* Probably End of DMA, Phase Mismatch or Loss of BSY.
-			 * We ack IRQ after clearing Mode Register. Workarounds
-			 * for End of DMA errata need to happen in DMA Mode.
-			 */
-
-			dsprintk(NDEBUG_INTR, instance, "interrupt in DMA mode\n");
-
-			int transferred;
-
-			if (!hostdata->connected)
-				panic("scsi%d : DMA interrupt with no connected cmd\n",
-				      instance->hostno);
-
-			transferred = hostdata->dmalen - NCR5380_dma_residual(instance);
-			hostdata->connected->SCp.this_residual -= transferred;
-			hostdata->connected->SCp.ptr += transferred;
-			hostdata->dmalen = 0;
-
-			/* FIXME: we need to poll briefly then defer a workqueue task ! */
-			NCR5380_poll_politely(hostdata, BUS_AND_STATUS_REG, BASR_ACK, 0, 2 * HZ);
-
-			NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
-			NCR5380_write(MODE_REG, MR_BASE);
-			NCR5380_read(RESET_PARITY_INTERRUPT_REG);
-		} else
-#endif /* REAL_DMA */
 		if ((NCR5380_read(CURRENT_SCSI_DATA_REG) & hostdata->id_mask) &&
 		    (sr & (SR_SEL | SR_IO | SR_BSY | SR_RST)) == (SR_SEL | SR_IO)) {
 			/* Probably reselected */
@@ -1495,7 +1436,7 @@ timeout:
 	return -1;
 }
 
-#if defined(REAL_DMA) || defined(PSEUDO_DMA) || defined (REAL_DMA_POLL)
+#if defined(PSEUDO_DMA)
 /*
  * Function : int NCR5380_transfer_dma (struct Scsi_Host *instance,
  * unsigned char *phase, int *count, unsigned char **data)
@@ -1525,34 +1466,14 @@ static int NCR5380_transfer_dma(struct S
 	register unsigned char *d = *data;
 	unsigned char tmp;
 	int foo;
-#if defined(REAL_DMA_POLL)
-	int cnt, toPIO;
-	unsigned char saved_data = 0, overrun = 0, residue;
-#endif
 
 	if ((tmp = (NCR5380_read(STATUS_REG) & PHASE_MASK)) != p) {
 		*phase = tmp;
 		return -1;
 	}
-#if defined(REAL_DMA) || defined(REAL_DMA_POLL)
-	if (p & SR_IO) {
-		if (!(hostdata->flags & FLAG_NO_DMA_FIXUPS))
-			c -= 2;
-	}
-	hostdata->dma_len = (p & SR_IO) ? NCR5380_dma_read_setup(instance, d, c) : NCR5380_dma_write_setup(instance, d, c);
-
-	dsprintk(NDEBUG_DMA, instance, "initializing DMA %s: length %d, address %p\n",
-	         (p & SR_IO) ? "receive" : "send", c, *data);
-#endif
 
 	NCR5380_write(TARGET_COMMAND_REG, PHASE_SR_TO_TCR(p));
 
-#ifdef REAL_DMA
-	NCR5380_write(MODE_REG, MR_BASE | MR_DMA_MODE | MR_MONITOR_BSY |
-	                        MR_ENABLE_EOP_INTR);
-#elif defined(REAL_DMA_POLL)
-	NCR5380_write(MODE_REG, MR_BASE | MR_DMA_MODE | MR_MONITOR_BSY);
-#else
 	/*
 	 * Note : on my sample board, watch-dog timeouts occurred when interrupts
 	 * were not disabled for the duration of a single DMA transfer, from
@@ -1564,7 +1485,6 @@ static int NCR5380_transfer_dma(struct S
 		                        MR_ENABLE_EOP_INTR);
 	else
 		NCR5380_write(MODE_REG, MR_BASE | MR_DMA_MODE | MR_MONITOR_BSY);
-#endif				/* def REAL_DMA */
 
 	dprintk(NDEBUG_DMA, "scsi%d : mode reg = 0x%X\n", instance->host_no, NCR5380_read(MODE_REG));
 
@@ -1584,14 +1504,8 @@ static int NCR5380_transfer_dma(struct S
 		io_recovery_delay(1);
 	}
 
-#if defined(REAL_DMA_POLL)
-	do {
-		tmp = NCR5380_read(BUS_AND_STATUS_REG);
-	} while ((tmp & BASR_PHASE_MATCH) && !(tmp & (BASR_BUSY_ERROR | BASR_END_DMA_TRANSFER)));
-
 /*
- * At this point, either we've completed DMA, or we have a phase mismatch,
- * or we've unexpectedly lost BUSY (which is a real error).
+ * A note regarding the DMA errata workarounds for early NMOS silicon.
  *
  * For DMA sends, we want to wait until the last byte has been
  * transferred out over the bus before we turn off DMA mode.  Alas, there
@@ -1618,79 +1532,18 @@ static int NCR5380_transfer_dma(struct S
  * properly, or the target switches to MESSAGE IN phase to signal a
  * disconnection (either operation bringing the DMA to a clean halt).
  * However, in order to handle scatter-receive, we must work around the
- * problem.  The chosen fix is to DMA N-2 bytes, then check for the
+ * problem.  The chosen fix is to DMA fewer bytes, then check for the
  * condition before taking the NCR5380 out of DMA mode.  One or two extra
  * bytes are transferred via PIO as necessary to fill out the original
  * request.
  */
 
 	if (p & SR_IO) {
-		if (!(hostdata->flags & FLAG_NO_DMA_FIXUPS)) {
-			udelay(10);
-			if ((NCR5380_read(BUS_AND_STATUS_REG) & (BASR_PHASE_MATCH | BASR_ACK)) ==
-			    (BASR_PHASE_MATCH | BASR_ACK)) {
-				saved_data = NCR5380_read(INPUT_DATA_REGISTER);
-				overrun = 1;
-			}
-		}
-	} else {
-		int limit = 100;
-		while (((tmp = NCR5380_read(BUS_AND_STATUS_REG)) & BASR_ACK) || (NCR5380_read(STATUS_REG) & SR_REQ)) {
-			if (!(tmp & BASR_PHASE_MATCH))
-				break;
-			if (--limit < 0)
-				break;
-		}
-	}
-
-	dsprintk(NDEBUG_DMA, "polled DMA transfer complete, basr 0x%02x, sr 0x%02x\n",
-	         tmp, NCR5380_read(STATUS_REG));
-
-	NCR5380_write(MODE_REG, MR_BASE);
-	NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
-
-	residue = NCR5380_dma_residual(instance);
-	c -= residue;
-	*count -= c;
-	*data += c;
-	*phase = NCR5380_read(STATUS_REG) & PHASE_MASK;
-
-	if (!(hostdata->flags & FLAG_NO_DMA_FIXUPS) &&
-	    *phase == p && (p & SR_IO) && residue == 0) {
-		if (overrun) {
-			dprintk(NDEBUG_DMA, "Got an input overrun, using saved byte\n");
-			**data = saved_data;
-			*data += 1;
-			*count -= 1;
-			cnt = toPIO = 1;
-		} else {
-			printk("No overrun??\n");
-			cnt = toPIO = 2;
-		}
-		dprintk(NDEBUG_DMA, "Doing %d-byte PIO to 0x%X\n", cnt, *data);
-		NCR5380_transfer_pio(instance, phase, &cnt, data);
-		*count -= toPIO - cnt;
-	}
-
-	dprintk(NDEBUG_DMA, "Return with data ptr = 0x%X, count %d, last 0x%X, next 0x%X\n", *data, *count, *(*data + *count - 1), *(*data + *count));
-	return 0;
-
-#elif defined(REAL_DMA)
-	return 0;
-#else				/* defined(REAL_DMA_POLL) */
-	if (p & SR_IO) {
 		foo = NCR5380_pread(instance, d,
 			hostdata->flags & FLAG_NO_DMA_FIXUP ? c : c - 1);
 		if (!foo && !(hostdata->flags & FLAG_NO_DMA_FIXUP)) {
 			/*
-			 * We can't disable DMA mode after successfully transferring
-			 * what we plan to be the last byte, since that would open up
-			 * a race condition where if the target asserted REQ before
-			 * we got the DMA mode reset, the NCR5380 would have latched
-			 * an additional byte into the INPUT DATA register and we'd
-			 * have dropped it.
-			 *
-			 * The workaround was to transfer one fewer bytes than we
+			 * The workaround was to transfer fewer bytes than we
 			 * intended to with the pseudo-DMA read function, wait for
 			 * the chip to latch the last byte, read it, and then disable
 			 * pseudo-DMA mode.
@@ -1738,9 +1591,8 @@ static int NCR5380_transfer_dma(struct S
 	*count = 0;
 	*phase = NCR5380_read(STATUS_REG) & PHASE_MASK;
 	return foo;
-#endif				/* def REAL_DMA */
 }
-#endif				/* defined(REAL_DMA) | defined(PSEUDO_DMA) */
+#endif /* PSEUDO_DMA */
 
 /*
  * Function : NCR5380_information_transfer (struct Scsi_Host *instance)
@@ -1831,7 +1683,7 @@ static void NCR5380_information_transfer
 				 * in an unconditional loop.
 				 */
 
-#if defined(PSEUDO_DMA) || defined(REAL_DMA_POLL)
+#if defined(PSEUDO_DMA)
 				transfersize = 0;
 				if (!cmd->device->borken)
 					transfersize = NCR5380_dma_xfer_len(instance, cmd, phase);
@@ -1855,7 +1707,7 @@ static void NCR5380_information_transfer
 					} else
 						cmd->SCp.this_residual -= transfersize - len;
 				} else
-#endif				/* defined(PSEUDO_DMA) || defined(REAL_DMA_POLL) */
+#endif /* PSEUDO_DMA */
 				{
 					/* Break up transfer into 3 ms chunks,
 					 * presuming 6 accesses per handshake.
@@ -2202,52 +2054,6 @@ static void NCR5380_reselect(struct Scsi
 	         scmd_id(tmp), tmp->device->lun, tmp->tag);
 }
 
-/*
- * Function : void NCR5380_dma_complete (struct Scsi_Host *instance)
- *
- * Purpose : called by interrupt handler when DMA finishes or a phase
- * mismatch occurs (which would finish the DMA transfer).
- *
- * Inputs : instance - this instance of the NCR5380.
- *
- * Returns : pointer to the scsi_cmnd structure for which the I_T_L
- * nexus has been reestablished, on failure NULL is returned.
- */
-
-#ifdef REAL_DMA
-static void NCR5380_dma_complete(NCR5380_instance * instance) {
-	struct NCR5380_hostdata *hostdata = shost_priv(instance);
-	int transferred;
-
-	/*
-	 * XXX this might not be right.
-	 *
-	 * Wait for final byte to transfer, ie wait for ACK to go false.
-	 *
-	 * We should use the Last Byte Sent bit, unfortunately this is
-	 * not available on the 5380/5381 (only the various CMOS chips)
-	 *
-	 * FIXME: timeout, and need to handle long timeout/irq case
-	 */
-
-	NCR5380_poll_politely(instance, BUS_AND_STATUS_REG, BASR_ACK, 0, 5*HZ);
-
-	NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
-
-	/*
-	 * The only places we should see a phase mismatch and have to send
-	 * data from the same set of pointers will be the data transfer
-	 * phases.  So, residual, requested length are only important here.
-	 */
-
-	if (!(hostdata->connected->SCp.phase & SR_CD)) {
-		transferred = instance->dmalen - NCR5380_dma_residual();
-		hostdata->connected->SCp.this_residual -= transferred;
-		hostdata->connected->SCp.ptr += transferred;
-	}
-}
-#endif				/* def REAL_DMA */
-
 /**
  * list_find_cmd - test for presence of a command in a linked list
  * @haystack: list of commands
@@ -2359,9 +2165,7 @@ static int NCR5380_abort(struct scsi_cmn
 	if (hostdata->connected == cmd) {
 		dsprintk(NDEBUG_ABORT, instance, "abort: cmd %p is connected\n", cmd);
 		hostdata->connected = NULL;
-#ifdef REAL_DMA
 		hostdata->dma_len = 0;
-#endif
 		if (do_abort(instance)) {
 			set_host_byte(cmd, DID_ERROR);
 			complete_cmd(instance, cmd);
@@ -2464,9 +2268,7 @@ static int NCR5380_bus_reset(struct scsi
 
 	for (i = 0; i < 8; ++i)
 		hostdata->busy[i] = 0;
-#ifdef REAL_DMA
 	hostdata->dma_len = 0;
-#endif
 
 	queue_work(hostdata->work_q, &hostdata->main_task);
 	spin_unlock_irqrestore(&hostdata->lock, flags);
Index: linux/drivers/scsi/NCR5380.h
===================================================================
--- linux.orig/drivers/scsi/NCR5380.h	2016-03-23 21:05:16.000000000 +1100
+++ linux/drivers/scsi/NCR5380.h	2016-03-23 21:09:22.000000000 +1100
@@ -239,9 +239,7 @@ struct NCR5380_hostdata {
 	struct Scsi_Host *host;			/* Host backpointer */
 	unsigned char id_mask, id_higher_mask;	/* 1 << id, all bits greater */
 	unsigned char busy[8];			/* index = target, bit = lun */
-#if defined(REAL_DMA) || defined(REAL_DMA_POLL)
 	int dma_len;				/* requested length of DMA */
-#endif
 	unsigned char last_message;		/* last message OUT */
 	struct scsi_cmnd *connected;		/* currently connected cmnd */
 	struct scsi_cmnd *selecting;		/* cmnd to be connected */
@@ -319,118 +317,8 @@ static void NCR5380_main(struct work_str
 static const char *NCR5380_info(struct Scsi_Host *instance);
 static void NCR5380_reselect(struct Scsi_Host *instance);
 static struct scsi_cmnd *NCR5380_select(struct Scsi_Host *, struct scsi_cmnd *);
-#if defined(PSEUDO_DMA) || defined(REAL_DMA) || defined(REAL_DMA_POLL)
 static int NCR5380_transfer_dma(struct Scsi_Host *instance, unsigned char *phase, int *count, unsigned char **data);
-#endif
 static int NCR5380_transfer_pio(struct Scsi_Host *instance, unsigned char *phase, int *count, unsigned char **data);
 
-#if (defined(REAL_DMA) || defined(REAL_DMA_POLL))
-
-#if defined(i386) || defined(__alpha__)
-
-/**
- *	NCR5380_pc_dma_setup		-	setup ISA DMA
- *	@instance: adapter to set up
- *	@ptr: block to transfer (virtual address)
- *	@count: number of bytes to transfer
- *	@mode: DMA controller mode to use
- *
- *	Program the DMA controller ready to perform an ISA DMA transfer
- *	on this chip.
- *
- *	Locks: takes and releases the ISA DMA lock.
- */
- 
-static __inline__ int NCR5380_pc_dma_setup(struct Scsi_Host *instance, unsigned char *ptr, unsigned int count, unsigned char mode)
-{
-	unsigned limit;
-	unsigned long bus_addr = virt_to_bus(ptr);
-	unsigned long flags;
-
-	if (instance->dma_channel <= 3) {
-		if (count > 65536)
-			count = 65536;
-		limit = 65536 - (bus_addr & 0xFFFF);
-	} else {
-		if (count > 65536 * 2)
-			count = 65536 * 2;
-		limit = 65536 * 2 - (bus_addr & 0x1FFFF);
-	}
-
-	if (count > limit)
-		count = limit;
-
-	if ((count & 1) || (bus_addr & 1))
-		panic("scsi%d : attempted unaligned DMA transfer\n", instance->host_no);
-	
-	flags=claim_dma_lock();
-	disable_dma(instance->dma_channel);
-	clear_dma_ff(instance->dma_channel);
-	set_dma_addr(instance->dma_channel, bus_addr);
-	set_dma_count(instance->dma_channel, count);
-	set_dma_mode(instance->dma_channel, mode);
-	enable_dma(instance->dma_channel);
-	release_dma_lock(flags);
-	
-	return count;
-}
-
-/**
- *	NCR5380_pc_dma_write_setup		-	setup ISA DMA write
- *	@instance: adapter to set up
- *	@ptr: block to transfer (virtual address)
- *	@count: number of bytes to transfer
- *
- *	Program the DMA controller ready to perform an ISA DMA write to the
- *	SCSI controller.
- *
- *	Locks: called routines take and release the ISA DMA lock.
- */
-
-static __inline__ int NCR5380_pc_dma_write_setup(struct Scsi_Host *instance, unsigned char *src, unsigned int count)
-{
-	return NCR5380_pc_dma_setup(instance, src, count, DMA_MODE_WRITE);
-}
-
-/**
- *	NCR5380_pc_dma_read_setup		-	setup ISA DMA read
- *	@instance: adapter to set up
- *	@ptr: block to transfer (virtual address)
- *	@count: number of bytes to transfer
- *
- *	Program the DMA controller ready to perform an ISA DMA read from the
- *	SCSI controller.
- *
- *	Locks: called routines take and release the ISA DMA lock.
- */
-
-static __inline__ int NCR5380_pc_dma_read_setup(struct Scsi_Host *instance, unsigned char *src, unsigned int count)
-{
-	return NCR5380_pc_dma_setup(instance, src, count, DMA_MODE_READ);
-}
-
-/**
- *	NCR5380_pc_dma_residual		-	return bytes left 
- *	@instance: adapter
- *
- *	Reports the number of bytes left over after the DMA was terminated.
- *
- *	Locks: takes and releases the ISA DMA lock.
- */
-
-static __inline__ int NCR5380_pc_dma_residual(struct Scsi_Host *instance)
-{
-	unsigned long flags;
-	int tmp;
-
-	flags = claim_dma_lock();
-	clear_dma_ff(instance->dma_channel);
-	tmp = get_dma_residue(instance->dma_channel);
-	release_dma_lock(flags);
-	
-	return tmp;
-}
-#endif				/* defined(i386) || defined(__alpha__) */
-#endif				/* defined(REAL_DMA)  */
 #endif				/* __KERNEL__ */
 #endif				/* NCR5380_H */
Index: linux/drivers/scsi/atari_NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/atari_NCR5380.c	2016-03-23 21:09:19.000000000 +1100
+++ linux/drivers/scsi/atari_NCR5380.c	2016-03-23 21:09:22.000000000 +1100
@@ -112,15 +112,9 @@
  * specific implementation of the NCR5380
  *
  * Either real DMA *or* pseudo DMA may be implemented
- * REAL functions :
- * NCR5380_REAL_DMA should be defined if real DMA is to be used.
  * Note that the DMA setup functions should return the number of bytes
  * that they were able to program the controller for.
  *
- * Also note that generic i386/PC versions of these macros are
- * available as NCR5380_i386_dma_write_setup,
- * NCR5380_i386_dma_read_setup, and NCR5380_i386_dma_residual.
- *
  * NCR5380_dma_write_setup(instance, src, count) - initialize
  * NCR5380_dma_read_setup(instance, dst, count) - initialize
  * NCR5380_dma_residual(instance); - residual count
@@ -586,9 +580,6 @@ static void prepare_info(struct Scsi_Hos
 #ifdef DIFFERENTIAL
 	         "DIFFERENTIAL "
 #endif
-#ifdef REAL_DMA
-	         "REAL_DMA "
-#endif
 #ifdef PARITY
 	         "PARITY "
 #endif
@@ -629,9 +620,8 @@ static int __init NCR5380_init(struct Sc
 #ifdef SUPPORT_TAGS
 	init_tags(hostdata);
 #endif
-#if defined (REAL_DMA)
 	hostdata->dma_len = 0;
-#endif
+
 	spin_lock_init(&hostdata->lock);
 	hostdata->connected = NULL;
 	hostdata->sensing = NULL;
@@ -974,11 +964,7 @@ static void NCR5380_main(struct work_str
 #endif
 			}
 		}
-		if (hostdata->connected
-#ifdef REAL_DMA
-		    && !hostdata->dma_len
-#endif
-		    ) {
+		if (hostdata->connected && !hostdata->dma_len) {
 			dsprintk(NDEBUG_MAIN, instance, "main: performing information transfer\n");
 			NCR5380_information_transfer(instance);
 			done = 0;
@@ -990,7 +976,6 @@ static void NCR5380_main(struct work_str
 }
 
 
-#ifdef REAL_DMA
 /*
  * Function : void NCR5380_dma_complete (struct Scsi_Host *instance)
  *
@@ -1071,7 +1056,6 @@ static void NCR5380_dma_complete(struct
 		}
 	}
 }
-#endif /* REAL_DMA */
 
 
 /**
@@ -1126,7 +1110,6 @@ static irqreturn_t NCR5380_intr(int irq,
 		dsprintk(NDEBUG_INTR, instance, "IRQ %d, BASR 0x%02x, SR 0x%02x, MR 0x%02x\n",
 		         irq, basr, sr, mr);
 
-#if defined(REAL_DMA)
 		if ((mr & MR_DMA_MODE) || (mr & MR_MONITOR_BSY)) {
 			/* Probably End of DMA, Phase Mismatch or Loss of BSY.
 			 * We ack IRQ after clearing Mode Register. Workarounds
@@ -1142,9 +1125,7 @@ static irqreturn_t NCR5380_intr(int irq,
 				NCR5380_write(MODE_REG, MR_BASE);
 				NCR5380_read(RESET_PARITY_INTERRUPT_REG);
 			}
-		} else
-#endif /* REAL_DMA */
-		if ((NCR5380_read(CURRENT_SCSI_DATA_REG) & hostdata->id_mask) &&
+		} else if ((NCR5380_read(CURRENT_SCSI_DATA_REG) & hostdata->id_mask) &&
 		    (sr & (SR_SEL | SR_IO | SR_BSY | SR_RST)) == (SR_SEL | SR_IO)) {
 			/* Probably reselected */
 			NCR5380_write(SELECT_ENABLE_REG, 0);
@@ -1710,7 +1691,7 @@ timeout:
 	return -1;
 }
 
-#if defined(REAL_DMA)
+
 /*
  * Function : int NCR5380_transfer_dma (struct Scsi_Host *instance,
  * unsigned char *phase, int *count, unsigned char **data)
@@ -1819,7 +1800,6 @@ static int NCR5380_transfer_dma(struct S
 
 	return 0;
 }
-#endif /* defined(REAL_DMA) */
 
 /*
  * Function : NCR5380_information_transfer (struct Scsi_Host *instance)
@@ -1866,7 +1846,6 @@ static void NCR5380_information_transfer
 			}
 #if defined(CONFIG_SUN3)
 			if (phase == PHASE_CMDOUT) {
-#if defined(REAL_DMA)
 				void *d;
 				unsigned long count;
 
@@ -1885,7 +1864,6 @@ static void NCR5380_information_transfer
 						sun3_dma_setup_done = cmd;
 					}
 				}
-#endif
 #ifdef SUN3_SCSI_VME
 				dregs->csr |= CSR_INTR;
 #endif
@@ -1943,12 +1921,6 @@ static void NCR5380_information_transfer
 				 * in an unconditional loop.
 				 */
 
-				/* ++roman: I suggest, this should be
-				 * #if def(REAL_DMA)
-				 * instead of leaving REAL_DMA out.
-				 */
-
-#if defined(REAL_DMA)
 #if !defined(CONFIG_SUN3)
 				transfersize = 0;
 				if (!cmd->device->borken)
@@ -1972,21 +1944,9 @@ static void NCR5380_information_transfer
 						do_abort(instance);
 						cmd->result = DID_ERROR << 16;
 						/* XXX - need to source or sink data here, as appropriate */
-					} else {
-#ifdef REAL_DMA
-						/* ++roman: When using real DMA,
-						 * information_transfer() should return after
-						 * starting DMA since it has nothing more to
-						 * do.
-						 */
+					} else
 						return;
-#else
-						cmd->SCp.this_residual -= transfersize - len;
-#endif
-					}
-				} else
-#endif /* defined(REAL_DMA) */
-				{
+				} else {
 					/* Break up transfer into 3 ms chunks,
 					 * presuming 6 accesses per handshake.
 					 */
@@ -1997,7 +1957,7 @@ static void NCR5380_information_transfer
 					                     (unsigned char **)&cmd->SCp.ptr);
 					cmd->SCp.this_residual -= transfersize - len;
 				}
-#if defined(CONFIG_SUN3) && defined(REAL_DMA)
+#if defined(CONFIG_SUN3)
 				/* if we had intended to dma that command clear it */
 				if (sun3_dma_setup_done == cmd)
 					sun3_dma_setup_done = NULL;
@@ -2305,7 +2265,7 @@ static void NCR5380_reselect(struct Scsi
 		return;
 	}
 
-#if defined(CONFIG_SUN3) && defined(REAL_DMA)
+#if defined(CONFIG_SUN3)
 	/* acknowledge toggle to MSGIN */
 	NCR5380_write(TARGET_COMMAND_REG, PHASE_SR_TO_TCR(PHASE_MSGIN));
 
@@ -2392,7 +2352,7 @@ static void NCR5380_reselect(struct Scsi
 		return;
 	}
 
-#if defined(CONFIG_SUN3) && defined(REAL_DMA)
+#if defined(CONFIG_SUN3)
 	/* engage dma setup for the command we just saw */
 	{
 		void *d;
@@ -2555,9 +2515,7 @@ static int NCR5380_abort(struct scsi_cmn
 	if (hostdata->connected == cmd) {
 		dsprintk(NDEBUG_ABORT, instance, "abort: cmd %p is connected\n", cmd);
 		hostdata->connected = NULL;
-#ifdef REAL_DMA
 		hostdata->dma_len = 0;
-#endif
 		if (do_abort(instance)) {
 			set_host_byte(cmd, DID_ERROR);
 			complete_cmd(instance, cmd);
@@ -2664,9 +2622,7 @@ static int NCR5380_bus_reset(struct scsi
 #endif
 	for (i = 0; i < 8; ++i)
 		hostdata->busy[i] = 0;
-#ifdef REAL_DMA
 	hostdata->dma_len = 0;
-#endif
 
 	queue_work(hostdata->work_q, &hostdata->main_task);
 	maybe_release_dma_irq(instance);
Index: linux/drivers/scsi/atari_scsi.c
===================================================================
--- linux.orig/drivers/scsi/atari_scsi.c	2016-03-23 21:05:16.000000000 +1100
+++ linux/drivers/scsi/atari_scsi.c	2016-03-23 21:09:22.000000000 +1100
@@ -85,7 +85,6 @@
 
 /* Definitions for the core NCR5380 driver. */
 
-#define REAL_DMA
 #define SUPPORT_TAGS
 #define MAX_TAGS                        32
 #define DMA_MIN_SIZE                    32
@@ -159,14 +158,11 @@ static inline unsigned long SCSI_DMA_GET
 	return adr;
 }
 
-#ifdef REAL_DMA
 static void atari_scsi_fetch_restbytes(void);
-#endif
 
 static unsigned char (*atari_scsi_reg_read)(unsigned char reg);
 static void (*atari_scsi_reg_write)(unsigned char reg, unsigned char value);
 
-#ifdef REAL_DMA
 static unsigned long	atari_dma_residual, atari_dma_startaddr;
 static short		atari_dma_active;
 /* pointer to the dribble buffer */
@@ -185,7 +181,6 @@ static char		*atari_dma_orig_addr;
 /* mask for address bits that can't be used with the ST-DMA */
 static unsigned long	atari_dma_stram_mask;
 #define STRAM_ADDR(a)	(((a) & atari_dma_stram_mask) == 0)
-#endif
 
 static int setup_can_queue = -1;
 module_param(setup_can_queue, int, 0);
@@ -201,8 +196,6 @@ static int setup_toshiba_delay = -1;
 module_param(setup_toshiba_delay, int, 0);
 
 
-#if defined(REAL_DMA)
-
 static int scsi_dma_is_ignored_buserr(unsigned char dma_stat)
 {
 	int i;
@@ -255,12 +248,9 @@ static void scsi_dma_buserr(int irq, voi
 }
 #endif
 
-#endif
-
 
 static irqreturn_t scsi_tt_intr(int irq, void *dev)
 {
-#ifdef REAL_DMA
 	struct Scsi_Host *instance = dev;
 	struct NCR5380_hostdata *hostdata = shost_priv(instance);
 	int dma_stat;
@@ -342,8 +332,6 @@ static irqreturn_t scsi_tt_intr(int irq,
 		tt_scsi_dma.dma_ctrl = 0;
 	}
 
-#endif /* REAL_DMA */
-
 	NCR5380_intr(irq, dev);
 
 	return IRQ_HANDLED;
@@ -352,7 +340,6 @@ static irqreturn_t scsi_tt_intr(int irq,
 
 static irqreturn_t scsi_falcon_intr(int irq, void *dev)
 {
-#ifdef REAL_DMA
 	struct Scsi_Host *instance = dev;
 	struct NCR5380_hostdata *hostdata = shost_priv(instance);
 	int dma_stat;
@@ -405,15 +392,12 @@ static irqreturn_t scsi_falcon_intr(int
 		atari_dma_orig_addr = NULL;
 	}
 
-#endif /* REAL_DMA */
-
 	NCR5380_intr(irq, dev);
 
 	return IRQ_HANDLED;
 }
 
 
-#ifdef REAL_DMA
 static void atari_scsi_fetch_restbytes(void)
 {
 	int nr;
@@ -436,7 +420,6 @@ static void atari_scsi_fetch_restbytes(v
 			*dst++ = *src++;
 	}
 }
-#endif /* REAL_DMA */
 
 
 /* This function releases the lock on the DMA chip if there is no
@@ -508,8 +491,6 @@ __setup("atascsi=", atari_scsi_setup);
 #endif /* !MODULE */
 
 
-#if defined(REAL_DMA)
-
 static unsigned long atari_scsi_dma_setup(struct Scsi_Host *instance,
 					  void *data, unsigned long count,
 					  int dir)
@@ -703,9 +684,6 @@ static unsigned long atari_dma_xfer_len(
 }
 
 
-#endif	/* REAL_DMA */
-
-
 /* NCR5380 register access functions
  *
  * There are separate functions for TT and Falcon, because the access
@@ -745,7 +723,6 @@ static int atari_scsi_bus_reset(struct s
 
 	local_irq_save(flags);
 
-#ifdef REAL_DMA
 	/* Abort a maybe active DMA transfer */
 	if (IS_A_TT()) {
 		tt_scsi_dma.dma_ctrl = 0;
@@ -754,7 +731,6 @@ static int atari_scsi_bus_reset(struct s
 		atari_dma_active = 0;
 		atari_dma_orig_addr = NULL;
 	}
-#endif
 
 	rv = NCR5380_bus_reset(cmd);
 
@@ -850,8 +826,6 @@ static int __init atari_scsi_probe(struc
 		}
 	}
 
-
-#ifdef REAL_DMA
 	/* If running on a Falcon and if there's TT-Ram (i.e., more than one
 	 * memory block, since there's always ST-Ram in a Falcon), then
 	 * allocate a STRAM_BUFFER_SIZE byte dribble buffer for transfers
@@ -867,7 +841,6 @@ static int __init atari_scsi_probe(struc
 		atari_dma_phys_buffer = atari_stram_to_phys(atari_dma_buffer);
 		atari_dma_orig_addr = 0;
 	}
-#endif
 
 	instance = scsi_host_alloc(&atari_scsi_template,
 	                           sizeof(struct NCR5380_hostdata));
@@ -897,7 +870,7 @@ static int __init atari_scsi_probe(struc
 			goto fail_irq;
 		}
 		tt_mfp.active_edge |= 0x80;	/* SCSI int on L->H */
-#ifdef REAL_DMA
+
 		tt_scsi_dma.dma_ctrl = 0;
 		atari_dma_residual = 0;
 
@@ -919,17 +892,14 @@ static int __init atari_scsi_probe(struc
 
 			hostdata->read_overruns = 4;
 		}
-#endif
 	} else {
 		/* Nothing to do for the interrupt: the ST-DMA is initialized
 		 * already.
 		 */
-#ifdef REAL_DMA
 		atari_dma_residual = 0;
 		atari_dma_active = 0;
 		atari_dma_stram_mask = (ATARIHW_PRESENT(EXTD_DMA) ? 0x00000000
 					: 0xff000000);
-#endif
 	}
 
 	NCR5380_maybe_reset_bus(instance);
Index: linux/drivers/scsi/sun3_scsi.c
===================================================================
--- linux.orig/drivers/scsi/sun3_scsi.c	2016-03-23 21:05:16.000000000 +1100
+++ linux/drivers/scsi/sun3_scsi.c	2016-03-23 21:09:22.000000000 +1100
@@ -38,7 +38,6 @@
 
 /* Definitions for the core NCR5380 driver. */
 
-#define REAL_DMA
 /* #define SUPPORT_TAGS */
 /* minimum number of bytes to do dma on */
 #define DMA_MIN_SIZE                    129
@@ -527,15 +526,9 @@ static int __init sun3_scsi_probe(struct
 	error = request_irq(instance->irq, scsi_sun3_intr, 0,
 	                    "NCR5380", instance);
 	if (error) {
-#ifdef REAL_DMA
 		pr_err(PFX "scsi%d: IRQ %d not free, bailing out\n",
 		       instance->host_no, instance->irq);
 		goto fail_irq;
-#else
-		pr_warn(PFX "scsi%d: IRQ %d not free, interrupts disabled\n",
-		        instance->host_no, instance->irq);
-		instance->irq = NO_IRQ;
-#endif
 	}
 
 	dregs->csr = 0;
@@ -565,8 +558,7 @@ static int __init sun3_scsi_probe(struct
 	return 0;
 
 fail_host:
-	if (instance->irq != NO_IRQ)
-		free_irq(instance->irq, instance);
+	free_irq(instance->irq, instance);
 fail_irq:
 	NCR5380_exit(instance);
 fail_init:
@@ -583,8 +575,7 @@ static int __exit sun3_scsi_remove(struc
 	struct Scsi_Host *instance = platform_get_drvdata(pdev);
 
 	scsi_remove_host(instance);
-	if (instance->irq != NO_IRQ)
-		free_irq(instance->irq, instance);
+	free_irq(instance->irq, instance);
 	NCR5380_exit(instance);
 	scsi_host_put(instance);
 	if (udc_regs)

^ permalink raw reply	[flat|nested] 60+ messages in thread

* [PATCH v4 03/23] ncr5380: Remove REAL_DMA and REAL_DMA_POLL macros
@ 2016-03-23 10:10   ` Finn Thain
  0 siblings, 0 replies; 60+ messages in thread
From: Finn Thain @ 2016-03-23 10:10 UTC (permalink / raw)
  To: James E.J. Bottomley, Martin K. Petersen, Michael Schmitz,
	linux-m68k, linux-scsi, linux-kernel
  Cc: Ondrej Zary, Sam Creasey

[-- Attachment #1: ncr5380-remove-REAL_DMA-macro --]
[-- Type: text/plain, Size: 30386 bytes --]

For the NCR5380.c core driver, these macros are never used.
If REAL_DMA were to be defined, compilation would fail.

For the atari_NCR5380.c core driver, REAL_DMA is always defined.

Hence these macros are pointless.

Signed-off-by: Finn Thain <fthain@telegraphics.com.au>
Reviewed-by: Hannes Reinecke <hare@suse.com>
Tested-by: Michael Schmitz <schmitzmic@gmail.com>
Tested-by: Ondrej Zary <linux@rainbow-software.org>

---
 drivers/scsi/NCR5380.c       |  218 +------------------------------------------
 drivers/scsi/NCR5380.h       |  112 ----------------------
 drivers/scsi/atari_NCR5380.c |   62 +-----------
 drivers/scsi/atari_scsi.c    |   32 ------
 drivers/scsi/sun3_scsi.c     |   13 --
 5 files changed, 22 insertions(+), 415 deletions(-)

Index: linux/drivers/scsi/NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/NCR5380.c	2016-03-23 21:09:20.000000000 +1100
+++ linux/drivers/scsi/NCR5380.c	2016-03-23 21:09:22.000000000 +1100
@@ -35,18 +35,10 @@
  * code so that everything does the same thing that's done at the
  * end of a pseudo-DMA read operation.
  *
- * 2.  Fix REAL_DMA (interrupt driven, polled works fine) -
- * basically, transfer size needs to be reduced by one
- * and the last byte read as is done with PSEUDO_DMA.
- *
  * 4.  Test SCSI-II tagged queueing (I have no devices which support
  * tagged queueing)
  */
 
-#ifndef notyet
-#undef REAL_DMA
-#endif
-
 #ifdef BOARD_REQUIRES_NO_DELAY
 #define io_recovery_delay(x)
 #else
@@ -131,12 +123,6 @@
  *
  * PSEUDO_DMA - if defined, PSEUDO DMA is used during the data transfer phases.
  *
- * REAL_DMA - if defined, REAL DMA is used during the data transfer phases.
- *
- * REAL_DMA_POLL - if defined, REAL DMA is used but the driver doesn't
- * rely on phase mismatch and EOP interrupts to determine end
- * of phase.
- *
  * These macros MUST be defined :
  *
  * NCR5380_read(register)  - read from the specified register
@@ -147,15 +133,9 @@
  * specific implementation of the NCR5380
  *
  * Either real DMA *or* pseudo DMA may be implemented
- * REAL functions :
- * NCR5380_REAL_DMA should be defined if real DMA is to be used.
  * Note that the DMA setup functions should return the number of bytes
  * that they were able to program the controller for.
  *
- * Also note that generic i386/PC versions of these macros are
- * available as NCR5380_i386_dma_write_setup,
- * NCR5380_i386_dma_read_setup, and NCR5380_i386_dma_residual.
- *
  * NCR5380_dma_write_setup(instance, src, count) - initialize
  * NCR5380_dma_read_setup(instance, dst, count) - initialize
  * NCR5380_dma_residual(instance); - residual count
@@ -486,12 +466,6 @@ static void prepare_info(struct Scsi_Hos
 #ifdef DIFFERENTIAL
 	         "DIFFERENTIAL "
 #endif
-#ifdef REAL_DMA
-	         "REAL_DMA "
-#endif
-#ifdef REAL_DMA_POLL
-	         "REAL_DMA_POLL "
-#endif
 #ifdef PARITY
 	         "PARITY "
 #endif
@@ -551,9 +525,8 @@ static int NCR5380_init(struct Scsi_Host
 			hostdata->id_higher_mask |= i;
 	for (i = 0; i < 8; ++i)
 		hostdata->busy[i] = 0;
-#ifdef REAL_DMA
-	hostdata->dmalen = 0;
-#endif
+	hostdata->dma_len = 0;
+
 	spin_lock_init(&hostdata->lock);
 	hostdata->connected = NULL;
 	hostdata->sensing = NULL;
@@ -850,11 +823,7 @@ static void NCR5380_main(struct work_str
 				requeue_cmd(instance, cmd);
 			}
 		}
-		if (hostdata->connected
-#ifdef REAL_DMA
-		    && !hostdata->dmalen
-#endif
-		    ) {
+		if (hostdata->connected && !hostdata->dma_len) {
 			dsprintk(NDEBUG_MAIN, instance, "main: performing information transfer\n");
 			NCR5380_information_transfer(instance);
 			done = 0;
@@ -919,34 +888,6 @@ static irqreturn_t NCR5380_intr(int irq,
 		dsprintk(NDEBUG_INTR, instance, "IRQ %d, BASR 0x%02x, SR 0x%02x, MR 0x%02x\n",
 		         irq, basr, sr, mr);
 
-#if defined(REAL_DMA)
-		if ((mr & MR_DMA_MODE) || (mr & MR_MONITOR_BSY)) {
-			/* Probably End of DMA, Phase Mismatch or Loss of BSY.
-			 * We ack IRQ after clearing Mode Register. Workarounds
-			 * for End of DMA errata need to happen in DMA Mode.
-			 */
-
-			dsprintk(NDEBUG_INTR, instance, "interrupt in DMA mode\n");
-
-			int transferred;
-
-			if (!hostdata->connected)
-				panic("scsi%d : DMA interrupt with no connected cmd\n",
-				      instance->hostno);
-
-			transferred = hostdata->dmalen - NCR5380_dma_residual(instance);
-			hostdata->connected->SCp.this_residual -= transferred;
-			hostdata->connected->SCp.ptr += transferred;
-			hostdata->dmalen = 0;
-
-			/* FIXME: we need to poll briefly then defer a workqueue task ! */
-			NCR5380_poll_politely(hostdata, BUS_AND_STATUS_REG, BASR_ACK, 0, 2 * HZ);
-
-			NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
-			NCR5380_write(MODE_REG, MR_BASE);
-			NCR5380_read(RESET_PARITY_INTERRUPT_REG);
-		} else
-#endif /* REAL_DMA */
 		if ((NCR5380_read(CURRENT_SCSI_DATA_REG) & hostdata->id_mask) &&
 		    (sr & (SR_SEL | SR_IO | SR_BSY | SR_RST)) == (SR_SEL | SR_IO)) {
 			/* Probably reselected */
@@ -1495,7 +1436,7 @@ timeout:
 	return -1;
 }
 
-#if defined(REAL_DMA) || defined(PSEUDO_DMA) || defined (REAL_DMA_POLL)
+#if defined(PSEUDO_DMA)
 /*
  * Function : int NCR5380_transfer_dma (struct Scsi_Host *instance,
  * unsigned char *phase, int *count, unsigned char **data)
@@ -1525,34 +1466,14 @@ static int NCR5380_transfer_dma(struct S
 	register unsigned char *d = *data;
 	unsigned char tmp;
 	int foo;
-#if defined(REAL_DMA_POLL)
-	int cnt, toPIO;
-	unsigned char saved_data = 0, overrun = 0, residue;
-#endif
 
 	if ((tmp = (NCR5380_read(STATUS_REG) & PHASE_MASK)) != p) {
 		*phase = tmp;
 		return -1;
 	}
-#if defined(REAL_DMA) || defined(REAL_DMA_POLL)
-	if (p & SR_IO) {
-		if (!(hostdata->flags & FLAG_NO_DMA_FIXUPS))
-			c -= 2;
-	}
-	hostdata->dma_len = (p & SR_IO) ? NCR5380_dma_read_setup(instance, d, c) : NCR5380_dma_write_setup(instance, d, c);
-
-	dsprintk(NDEBUG_DMA, instance, "initializing DMA %s: length %d, address %p\n",
-	         (p & SR_IO) ? "receive" : "send", c, *data);
-#endif
 
 	NCR5380_write(TARGET_COMMAND_REG, PHASE_SR_TO_TCR(p));
 
-#ifdef REAL_DMA
-	NCR5380_write(MODE_REG, MR_BASE | MR_DMA_MODE | MR_MONITOR_BSY |
-	                        MR_ENABLE_EOP_INTR);
-#elif defined(REAL_DMA_POLL)
-	NCR5380_write(MODE_REG, MR_BASE | MR_DMA_MODE | MR_MONITOR_BSY);
-#else
 	/*
 	 * Note : on my sample board, watch-dog timeouts occurred when interrupts
 	 * were not disabled for the duration of a single DMA transfer, from
@@ -1564,7 +1485,6 @@ static int NCR5380_transfer_dma(struct S
 		                        MR_ENABLE_EOP_INTR);
 	else
 		NCR5380_write(MODE_REG, MR_BASE | MR_DMA_MODE | MR_MONITOR_BSY);
-#endif				/* def REAL_DMA */
 
 	dprintk(NDEBUG_DMA, "scsi%d : mode reg = 0x%X\n", instance->host_no, NCR5380_read(MODE_REG));
 
@@ -1584,14 +1504,8 @@ static int NCR5380_transfer_dma(struct S
 		io_recovery_delay(1);
 	}
 
-#if defined(REAL_DMA_POLL)
-	do {
-		tmp = NCR5380_read(BUS_AND_STATUS_REG);
-	} while ((tmp & BASR_PHASE_MATCH) && !(tmp & (BASR_BUSY_ERROR | BASR_END_DMA_TRANSFER)));
-
 /*
- * At this point, either we've completed DMA, or we have a phase mismatch,
- * or we've unexpectedly lost BUSY (which is a real error).
+ * A note regarding the DMA errata workarounds for early NMOS silicon.
  *
  * For DMA sends, we want to wait until the last byte has been
  * transferred out over the bus before we turn off DMA mode.  Alas, there
@@ -1618,79 +1532,18 @@ static int NCR5380_transfer_dma(struct S
  * properly, or the target switches to MESSAGE IN phase to signal a
  * disconnection (either operation bringing the DMA to a clean halt).
  * However, in order to handle scatter-receive, we must work around the
- * problem.  The chosen fix is to DMA N-2 bytes, then check for the
+ * problem.  The chosen fix is to DMA fewer bytes, then check for the
  * condition before taking the NCR5380 out of DMA mode.  One or two extra
  * bytes are transferred via PIO as necessary to fill out the original
  * request.
  */
 
 	if (p & SR_IO) {
-		if (!(hostdata->flags & FLAG_NO_DMA_FIXUPS)) {
-			udelay(10);
-			if ((NCR5380_read(BUS_AND_STATUS_REG) & (BASR_PHASE_MATCH | BASR_ACK)) ==
-			    (BASR_PHASE_MATCH | BASR_ACK)) {
-				saved_data = NCR5380_read(INPUT_DATA_REGISTER);
-				overrun = 1;
-			}
-		}
-	} else {
-		int limit = 100;
-		while (((tmp = NCR5380_read(BUS_AND_STATUS_REG)) & BASR_ACK) || (NCR5380_read(STATUS_REG) & SR_REQ)) {
-			if (!(tmp & BASR_PHASE_MATCH))
-				break;
-			if (--limit < 0)
-				break;
-		}
-	}
-
-	dsprintk(NDEBUG_DMA, "polled DMA transfer complete, basr 0x%02x, sr 0x%02x\n",
-	         tmp, NCR5380_read(STATUS_REG));
-
-	NCR5380_write(MODE_REG, MR_BASE);
-	NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
-
-	residue = NCR5380_dma_residual(instance);
-	c -= residue;
-	*count -= c;
-	*data += c;
-	*phase = NCR5380_read(STATUS_REG) & PHASE_MASK;
-
-	if (!(hostdata->flags & FLAG_NO_DMA_FIXUPS) &&
-	    *phase == p && (p & SR_IO) && residue == 0) {
-		if (overrun) {
-			dprintk(NDEBUG_DMA, "Got an input overrun, using saved byte\n");
-			**data = saved_data;
-			*data += 1;
-			*count -= 1;
-			cnt = toPIO = 1;
-		} else {
-			printk("No overrun??\n");
-			cnt = toPIO = 2;
-		}
-		dprintk(NDEBUG_DMA, "Doing %d-byte PIO to 0x%X\n", cnt, *data);
-		NCR5380_transfer_pio(instance, phase, &cnt, data);
-		*count -= toPIO - cnt;
-	}
-
-	dprintk(NDEBUG_DMA, "Return with data ptr = 0x%X, count %d, last 0x%X, next 0x%X\n", *data, *count, *(*data + *count - 1), *(*data + *count));
-	return 0;
-
-#elif defined(REAL_DMA)
-	return 0;
-#else				/* defined(REAL_DMA_POLL) */
-	if (p & SR_IO) {
 		foo = NCR5380_pread(instance, d,
 			hostdata->flags & FLAG_NO_DMA_FIXUP ? c : c - 1);
 		if (!foo && !(hostdata->flags & FLAG_NO_DMA_FIXUP)) {
 			/*
-			 * We can't disable DMA mode after successfully transferring
-			 * what we plan to be the last byte, since that would open up
-			 * a race condition where if the target asserted REQ before
-			 * we got the DMA mode reset, the NCR5380 would have latched
-			 * an additional byte into the INPUT DATA register and we'd
-			 * have dropped it.
-			 *
-			 * The workaround was to transfer one fewer bytes than we
+			 * The workaround was to transfer fewer bytes than we
 			 * intended to with the pseudo-DMA read function, wait for
 			 * the chip to latch the last byte, read it, and then disable
 			 * pseudo-DMA mode.
@@ -1738,9 +1591,8 @@ static int NCR5380_transfer_dma(struct S
 	*count = 0;
 	*phase = NCR5380_read(STATUS_REG) & PHASE_MASK;
 	return foo;
-#endif				/* def REAL_DMA */
 }
-#endif				/* defined(REAL_DMA) | defined(PSEUDO_DMA) */
+#endif /* PSEUDO_DMA */
 
 /*
  * Function : NCR5380_information_transfer (struct Scsi_Host *instance)
@@ -1831,7 +1683,7 @@ static void NCR5380_information_transfer
 				 * in an unconditional loop.
 				 */
 
-#if defined(PSEUDO_DMA) || defined(REAL_DMA_POLL)
+#if defined(PSEUDO_DMA)
 				transfersize = 0;
 				if (!cmd->device->borken)
 					transfersize = NCR5380_dma_xfer_len(instance, cmd, phase);
@@ -1855,7 +1707,7 @@ static void NCR5380_information_transfer
 					} else
 						cmd->SCp.this_residual -= transfersize - len;
 				} else
-#endif				/* defined(PSEUDO_DMA) || defined(REAL_DMA_POLL) */
+#endif /* PSEUDO_DMA */
 				{
 					/* Break up transfer into 3 ms chunks,
 					 * presuming 6 accesses per handshake.
@@ -2202,52 +2054,6 @@ static void NCR5380_reselect(struct Scsi
 	         scmd_id(tmp), tmp->device->lun, tmp->tag);
 }
 
-/*
- * Function : void NCR5380_dma_complete (struct Scsi_Host *instance)
- *
- * Purpose : called by interrupt handler when DMA finishes or a phase
- * mismatch occurs (which would finish the DMA transfer).
- *
- * Inputs : instance - this instance of the NCR5380.
- *
- * Returns : pointer to the scsi_cmnd structure for which the I_T_L
- * nexus has been reestablished, on failure NULL is returned.
- */
-
-#ifdef REAL_DMA
-static void NCR5380_dma_complete(NCR5380_instance * instance) {
-	struct NCR5380_hostdata *hostdata = shost_priv(instance);
-	int transferred;
-
-	/*
-	 * XXX this might not be right.
-	 *
-	 * Wait for final byte to transfer, ie wait for ACK to go false.
-	 *
-	 * We should use the Last Byte Sent bit, unfortunately this is
-	 * not available on the 5380/5381 (only the various CMOS chips)
-	 *
-	 * FIXME: timeout, and need to handle long timeout/irq case
-	 */
-
-	NCR5380_poll_politely(instance, BUS_AND_STATUS_REG, BASR_ACK, 0, 5*HZ);
-
-	NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
-
-	/*
-	 * The only places we should see a phase mismatch and have to send
-	 * data from the same set of pointers will be the data transfer
-	 * phases.  So, residual, requested length are only important here.
-	 */
-
-	if (!(hostdata->connected->SCp.phase & SR_CD)) {
-		transferred = instance->dmalen - NCR5380_dma_residual();
-		hostdata->connected->SCp.this_residual -= transferred;
-		hostdata->connected->SCp.ptr += transferred;
-	}
-}
-#endif				/* def REAL_DMA */
-
 /**
  * list_find_cmd - test for presence of a command in a linked list
  * @haystack: list of commands
@@ -2359,9 +2165,7 @@ static int NCR5380_abort(struct scsi_cmn
 	if (hostdata->connected == cmd) {
 		dsprintk(NDEBUG_ABORT, instance, "abort: cmd %p is connected\n", cmd);
 		hostdata->connected = NULL;
-#ifdef REAL_DMA
 		hostdata->dma_len = 0;
-#endif
 		if (do_abort(instance)) {
 			set_host_byte(cmd, DID_ERROR);
 			complete_cmd(instance, cmd);
@@ -2464,9 +2268,7 @@ static int NCR5380_bus_reset(struct scsi
 
 	for (i = 0; i < 8; ++i)
 		hostdata->busy[i] = 0;
-#ifdef REAL_DMA
 	hostdata->dma_len = 0;
-#endif
 
 	queue_work(hostdata->work_q, &hostdata->main_task);
 	spin_unlock_irqrestore(&hostdata->lock, flags);
Index: linux/drivers/scsi/NCR5380.h
===================================================================
--- linux.orig/drivers/scsi/NCR5380.h	2016-03-23 21:05:16.000000000 +1100
+++ linux/drivers/scsi/NCR5380.h	2016-03-23 21:09:22.000000000 +1100
@@ -239,9 +239,7 @@ struct NCR5380_hostdata {
 	struct Scsi_Host *host;			/* Host backpointer */
 	unsigned char id_mask, id_higher_mask;	/* 1 << id, all bits greater */
 	unsigned char busy[8];			/* index = target, bit = lun */
-#if defined(REAL_DMA) || defined(REAL_DMA_POLL)
 	int dma_len;				/* requested length of DMA */
-#endif
 	unsigned char last_message;		/* last message OUT */
 	struct scsi_cmnd *connected;		/* currently connected cmnd */
 	struct scsi_cmnd *selecting;		/* cmnd to be connected */
@@ -319,118 +317,8 @@ static void NCR5380_main(struct work_str
 static const char *NCR5380_info(struct Scsi_Host *instance);
 static void NCR5380_reselect(struct Scsi_Host *instance);
 static struct scsi_cmnd *NCR5380_select(struct Scsi_Host *, struct scsi_cmnd *);
-#if defined(PSEUDO_DMA) || defined(REAL_DMA) || defined(REAL_DMA_POLL)
 static int NCR5380_transfer_dma(struct Scsi_Host *instance, unsigned char *phase, int *count, unsigned char **data);
-#endif
 static int NCR5380_transfer_pio(struct Scsi_Host *instance, unsigned char *phase, int *count, unsigned char **data);
 
-#if (defined(REAL_DMA) || defined(REAL_DMA_POLL))
-
-#if defined(i386) || defined(__alpha__)
-
-/**
- *	NCR5380_pc_dma_setup		-	setup ISA DMA
- *	@instance: adapter to set up
- *	@ptr: block to transfer (virtual address)
- *	@count: number of bytes to transfer
- *	@mode: DMA controller mode to use
- *
- *	Program the DMA controller ready to perform an ISA DMA transfer
- *	on this chip.
- *
- *	Locks: takes and releases the ISA DMA lock.
- */
- 
-static __inline__ int NCR5380_pc_dma_setup(struct Scsi_Host *instance, unsigned char *ptr, unsigned int count, unsigned char mode)
-{
-	unsigned limit;
-	unsigned long bus_addr = virt_to_bus(ptr);
-	unsigned long flags;
-
-	if (instance->dma_channel <= 3) {
-		if (count > 65536)
-			count = 65536;
-		limit = 65536 - (bus_addr & 0xFFFF);
-	} else {
-		if (count > 65536 * 2)
-			count = 65536 * 2;
-		limit = 65536 * 2 - (bus_addr & 0x1FFFF);
-	}
-
-	if (count > limit)
-		count = limit;
-
-	if ((count & 1) || (bus_addr & 1))
-		panic("scsi%d : attempted unaligned DMA transfer\n", instance->host_no);
-	
-	flags=claim_dma_lock();
-	disable_dma(instance->dma_channel);
-	clear_dma_ff(instance->dma_channel);
-	set_dma_addr(instance->dma_channel, bus_addr);
-	set_dma_count(instance->dma_channel, count);
-	set_dma_mode(instance->dma_channel, mode);
-	enable_dma(instance->dma_channel);
-	release_dma_lock(flags);
-	
-	return count;
-}
-
-/**
- *	NCR5380_pc_dma_write_setup		-	setup ISA DMA write
- *	@instance: adapter to set up
- *	@ptr: block to transfer (virtual address)
- *	@count: number of bytes to transfer
- *
- *	Program the DMA controller ready to perform an ISA DMA write to the
- *	SCSI controller.
- *
- *	Locks: called routines take and release the ISA DMA lock.
- */
-
-static __inline__ int NCR5380_pc_dma_write_setup(struct Scsi_Host *instance, unsigned char *src, unsigned int count)
-{
-	return NCR5380_pc_dma_setup(instance, src, count, DMA_MODE_WRITE);
-}
-
-/**
- *	NCR5380_pc_dma_read_setup		-	setup ISA DMA read
- *	@instance: adapter to set up
- *	@ptr: block to transfer (virtual address)
- *	@count: number of bytes to transfer
- *
- *	Program the DMA controller ready to perform an ISA DMA read from the
- *	SCSI controller.
- *
- *	Locks: called routines take and release the ISA DMA lock.
- */
-
-static __inline__ int NCR5380_pc_dma_read_setup(struct Scsi_Host *instance, unsigned char *src, unsigned int count)
-{
-	return NCR5380_pc_dma_setup(instance, src, count, DMA_MODE_READ);
-}
-
-/**
- *	NCR5380_pc_dma_residual		-	return bytes left 
- *	@instance: adapter
- *
- *	Reports the number of bytes left over after the DMA was terminated.
- *
- *	Locks: takes and releases the ISA DMA lock.
- */
-
-static __inline__ int NCR5380_pc_dma_residual(struct Scsi_Host *instance)
-{
-	unsigned long flags;
-	int tmp;
-
-	flags = claim_dma_lock();
-	clear_dma_ff(instance->dma_channel);
-	tmp = get_dma_residue(instance->dma_channel);
-	release_dma_lock(flags);
-	
-	return tmp;
-}
-#endif				/* defined(i386) || defined(__alpha__) */
-#endif				/* defined(REAL_DMA)  */
 #endif				/* __KERNEL__ */
 #endif				/* NCR5380_H */
Index: linux/drivers/scsi/atari_NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/atari_NCR5380.c	2016-03-23 21:09:19.000000000 +1100
+++ linux/drivers/scsi/atari_NCR5380.c	2016-03-23 21:09:22.000000000 +1100
@@ -112,15 +112,9 @@
  * specific implementation of the NCR5380
  *
  * Either real DMA *or* pseudo DMA may be implemented
- * REAL functions :
- * NCR5380_REAL_DMA should be defined if real DMA is to be used.
  * Note that the DMA setup functions should return the number of bytes
  * that they were able to program the controller for.
  *
- * Also note that generic i386/PC versions of these macros are
- * available as NCR5380_i386_dma_write_setup,
- * NCR5380_i386_dma_read_setup, and NCR5380_i386_dma_residual.
- *
  * NCR5380_dma_write_setup(instance, src, count) - initialize
  * NCR5380_dma_read_setup(instance, dst, count) - initialize
  * NCR5380_dma_residual(instance); - residual count
@@ -586,9 +580,6 @@ static void prepare_info(struct Scsi_Hos
 #ifdef DIFFERENTIAL
 	         "DIFFERENTIAL "
 #endif
-#ifdef REAL_DMA
-	         "REAL_DMA "
-#endif
 #ifdef PARITY
 	         "PARITY "
 #endif
@@ -629,9 +620,8 @@ static int __init NCR5380_init(struct Sc
 #ifdef SUPPORT_TAGS
 	init_tags(hostdata);
 #endif
-#if defined (REAL_DMA)
 	hostdata->dma_len = 0;
-#endif
+
 	spin_lock_init(&hostdata->lock);
 	hostdata->connected = NULL;
 	hostdata->sensing = NULL;
@@ -974,11 +964,7 @@ static void NCR5380_main(struct work_str
 #endif
 			}
 		}
-		if (hostdata->connected
-#ifdef REAL_DMA
-		    && !hostdata->dma_len
-#endif
-		    ) {
+		if (hostdata->connected && !hostdata->dma_len) {
 			dsprintk(NDEBUG_MAIN, instance, "main: performing information transfer\n");
 			NCR5380_information_transfer(instance);
 			done = 0;
@@ -990,7 +976,6 @@ static void NCR5380_main(struct work_str
 }
 
 
-#ifdef REAL_DMA
 /*
  * Function : void NCR5380_dma_complete (struct Scsi_Host *instance)
  *
@@ -1071,7 +1056,6 @@ static void NCR5380_dma_complete(struct
 		}
 	}
 }
-#endif /* REAL_DMA */
 
 
 /**
@@ -1126,7 +1110,6 @@ static irqreturn_t NCR5380_intr(int irq,
 		dsprintk(NDEBUG_INTR, instance, "IRQ %d, BASR 0x%02x, SR 0x%02x, MR 0x%02x\n",
 		         irq, basr, sr, mr);
 
-#if defined(REAL_DMA)
 		if ((mr & MR_DMA_MODE) || (mr & MR_MONITOR_BSY)) {
 			/* Probably End of DMA, Phase Mismatch or Loss of BSY.
 			 * We ack IRQ after clearing Mode Register. Workarounds
@@ -1142,9 +1125,7 @@ static irqreturn_t NCR5380_intr(int irq,
 				NCR5380_write(MODE_REG, MR_BASE);
 				NCR5380_read(RESET_PARITY_INTERRUPT_REG);
 			}
-		} else
-#endif /* REAL_DMA */
-		if ((NCR5380_read(CURRENT_SCSI_DATA_REG) & hostdata->id_mask) &&
+		} else if ((NCR5380_read(CURRENT_SCSI_DATA_REG) & hostdata->id_mask) &&
 		    (sr & (SR_SEL | SR_IO | SR_BSY | SR_RST)) == (SR_SEL | SR_IO)) {
 			/* Probably reselected */
 			NCR5380_write(SELECT_ENABLE_REG, 0);
@@ -1710,7 +1691,7 @@ timeout:
 	return -1;
 }
 
-#if defined(REAL_DMA)
+
 /*
  * Function : int NCR5380_transfer_dma (struct Scsi_Host *instance,
  * unsigned char *phase, int *count, unsigned char **data)
@@ -1819,7 +1800,6 @@ static int NCR5380_transfer_dma(struct S
 
 	return 0;
 }
-#endif /* defined(REAL_DMA) */
 
 /*
  * Function : NCR5380_information_transfer (struct Scsi_Host *instance)
@@ -1866,7 +1846,6 @@ static void NCR5380_information_transfer
 			}
 #if defined(CONFIG_SUN3)
 			if (phase == PHASE_CMDOUT) {
-#if defined(REAL_DMA)
 				void *d;
 				unsigned long count;
 
@@ -1885,7 +1864,6 @@ static void NCR5380_information_transfer
 						sun3_dma_setup_done = cmd;
 					}
 				}
-#endif
 #ifdef SUN3_SCSI_VME
 				dregs->csr |= CSR_INTR;
 #endif
@@ -1943,12 +1921,6 @@ static void NCR5380_information_transfer
 				 * in an unconditional loop.
 				 */
 
-				/* ++roman: I suggest, this should be
-				 * #if def(REAL_DMA)
-				 * instead of leaving REAL_DMA out.
-				 */
-
-#if defined(REAL_DMA)
 #if !defined(CONFIG_SUN3)
 				transfersize = 0;
 				if (!cmd->device->borken)
@@ -1972,21 +1944,9 @@ static void NCR5380_information_transfer
 						do_abort(instance);
 						cmd->result = DID_ERROR << 16;
 						/* XXX - need to source or sink data here, as appropriate */
-					} else {
-#ifdef REAL_DMA
-						/* ++roman: When using real DMA,
-						 * information_transfer() should return after
-						 * starting DMA since it has nothing more to
-						 * do.
-						 */
+					} else
 						return;
-#else
-						cmd->SCp.this_residual -= transfersize - len;
-#endif
-					}
-				} else
-#endif /* defined(REAL_DMA) */
-				{
+				} else {
 					/* Break up transfer into 3 ms chunks,
 					 * presuming 6 accesses per handshake.
 					 */
@@ -1997,7 +1957,7 @@ static void NCR5380_information_transfer
 					                     (unsigned char **)&cmd->SCp.ptr);
 					cmd->SCp.this_residual -= transfersize - len;
 				}
-#if defined(CONFIG_SUN3) && defined(REAL_DMA)
+#if defined(CONFIG_SUN3)
 				/* if we had intended to dma that command clear it */
 				if (sun3_dma_setup_done == cmd)
 					sun3_dma_setup_done = NULL;
@@ -2305,7 +2265,7 @@ static void NCR5380_reselect(struct Scsi
 		return;
 	}
 
-#if defined(CONFIG_SUN3) && defined(REAL_DMA)
+#if defined(CONFIG_SUN3)
 	/* acknowledge toggle to MSGIN */
 	NCR5380_write(TARGET_COMMAND_REG, PHASE_SR_TO_TCR(PHASE_MSGIN));
 
@@ -2392,7 +2352,7 @@ static void NCR5380_reselect(struct Scsi
 		return;
 	}
 
-#if defined(CONFIG_SUN3) && defined(REAL_DMA)
+#if defined(CONFIG_SUN3)
 	/* engage dma setup for the command we just saw */
 	{
 		void *d;
@@ -2555,9 +2515,7 @@ static int NCR5380_abort(struct scsi_cmn
 	if (hostdata->connected == cmd) {
 		dsprintk(NDEBUG_ABORT, instance, "abort: cmd %p is connected\n", cmd);
 		hostdata->connected = NULL;
-#ifdef REAL_DMA
 		hostdata->dma_len = 0;
-#endif
 		if (do_abort(instance)) {
 			set_host_byte(cmd, DID_ERROR);
 			complete_cmd(instance, cmd);
@@ -2664,9 +2622,7 @@ static int NCR5380_bus_reset(struct scsi
 #endif
 	for (i = 0; i < 8; ++i)
 		hostdata->busy[i] = 0;
-#ifdef REAL_DMA
 	hostdata->dma_len = 0;
-#endif
 
 	queue_work(hostdata->work_q, &hostdata->main_task);
 	maybe_release_dma_irq(instance);
Index: linux/drivers/scsi/atari_scsi.c
===================================================================
--- linux.orig/drivers/scsi/atari_scsi.c	2016-03-23 21:05:16.000000000 +1100
+++ linux/drivers/scsi/atari_scsi.c	2016-03-23 21:09:22.000000000 +1100
@@ -85,7 +85,6 @@
 
 /* Definitions for the core NCR5380 driver. */
 
-#define REAL_DMA
 #define SUPPORT_TAGS
 #define MAX_TAGS                        32
 #define DMA_MIN_SIZE                    32
@@ -159,14 +158,11 @@ static inline unsigned long SCSI_DMA_GET
 	return adr;
 }
 
-#ifdef REAL_DMA
 static void atari_scsi_fetch_restbytes(void);
-#endif
 
 static unsigned char (*atari_scsi_reg_read)(unsigned char reg);
 static void (*atari_scsi_reg_write)(unsigned char reg, unsigned char value);
 
-#ifdef REAL_DMA
 static unsigned long	atari_dma_residual, atari_dma_startaddr;
 static short		atari_dma_active;
 /* pointer to the dribble buffer */
@@ -185,7 +181,6 @@ static char		*atari_dma_orig_addr;
 /* mask for address bits that can't be used with the ST-DMA */
 static unsigned long	atari_dma_stram_mask;
 #define STRAM_ADDR(a)	(((a) & atari_dma_stram_mask) == 0)
-#endif
 
 static int setup_can_queue = -1;
 module_param(setup_can_queue, int, 0);
@@ -201,8 +196,6 @@ static int setup_toshiba_delay = -1;
 module_param(setup_toshiba_delay, int, 0);
 
 
-#if defined(REAL_DMA)
-
 static int scsi_dma_is_ignored_buserr(unsigned char dma_stat)
 {
 	int i;
@@ -255,12 +248,9 @@ static void scsi_dma_buserr(int irq, voi
 }
 #endif
 
-#endif
-
 
 static irqreturn_t scsi_tt_intr(int irq, void *dev)
 {
-#ifdef REAL_DMA
 	struct Scsi_Host *instance = dev;
 	struct NCR5380_hostdata *hostdata = shost_priv(instance);
 	int dma_stat;
@@ -342,8 +332,6 @@ static irqreturn_t scsi_tt_intr(int irq,
 		tt_scsi_dma.dma_ctrl = 0;
 	}
 
-#endif /* REAL_DMA */
-
 	NCR5380_intr(irq, dev);
 
 	return IRQ_HANDLED;
@@ -352,7 +340,6 @@ static irqreturn_t scsi_tt_intr(int irq,
 
 static irqreturn_t scsi_falcon_intr(int irq, void *dev)
 {
-#ifdef REAL_DMA
 	struct Scsi_Host *instance = dev;
 	struct NCR5380_hostdata *hostdata = shost_priv(instance);
 	int dma_stat;
@@ -405,15 +392,12 @@ static irqreturn_t scsi_falcon_intr(int
 		atari_dma_orig_addr = NULL;
 	}
 
-#endif /* REAL_DMA */
-
 	NCR5380_intr(irq, dev);
 
 	return IRQ_HANDLED;
 }
 
 
-#ifdef REAL_DMA
 static void atari_scsi_fetch_restbytes(void)
 {
 	int nr;
@@ -436,7 +420,6 @@ static void atari_scsi_fetch_restbytes(v
 			*dst++ = *src++;
 	}
 }
-#endif /* REAL_DMA */
 
 
 /* This function releases the lock on the DMA chip if there is no
@@ -508,8 +491,6 @@ __setup("atascsi=", atari_scsi_setup);
 #endif /* !MODULE */
 
 
-#if defined(REAL_DMA)
-
 static unsigned long atari_scsi_dma_setup(struct Scsi_Host *instance,
 					  void *data, unsigned long count,
 					  int dir)
@@ -703,9 +684,6 @@ static unsigned long atari_dma_xfer_len(
 }
 
 
-#endif	/* REAL_DMA */
-
-
 /* NCR5380 register access functions
  *
  * There are separate functions for TT and Falcon, because the access
@@ -745,7 +723,6 @@ static int atari_scsi_bus_reset(struct s
 
 	local_irq_save(flags);
 
-#ifdef REAL_DMA
 	/* Abort a maybe active DMA transfer */
 	if (IS_A_TT()) {
 		tt_scsi_dma.dma_ctrl = 0;
@@ -754,7 +731,6 @@ static int atari_scsi_bus_reset(struct s
 		atari_dma_active = 0;
 		atari_dma_orig_addr = NULL;
 	}
-#endif
 
 	rv = NCR5380_bus_reset(cmd);
 
@@ -850,8 +826,6 @@ static int __init atari_scsi_probe(struc
 		}
 	}
 
-
-#ifdef REAL_DMA
 	/* If running on a Falcon and if there's TT-Ram (i.e., more than one
 	 * memory block, since there's always ST-Ram in a Falcon), then
 	 * allocate a STRAM_BUFFER_SIZE byte dribble buffer for transfers
@@ -867,7 +841,6 @@ static int __init atari_scsi_probe(struc
 		atari_dma_phys_buffer = atari_stram_to_phys(atari_dma_buffer);
 		atari_dma_orig_addr = 0;
 	}
-#endif
 
 	instance = scsi_host_alloc(&atari_scsi_template,
 	                           sizeof(struct NCR5380_hostdata));
@@ -897,7 +870,7 @@ static int __init atari_scsi_probe(struc
 			goto fail_irq;
 		}
 		tt_mfp.active_edge |= 0x80;	/* SCSI int on L->H */
-#ifdef REAL_DMA
+
 		tt_scsi_dma.dma_ctrl = 0;
 		atari_dma_residual = 0;
 
@@ -919,17 +892,14 @@ static int __init atari_scsi_probe(struc
 
 			hostdata->read_overruns = 4;
 		}
-#endif
 	} else {
 		/* Nothing to do for the interrupt: the ST-DMA is initialized
 		 * already.
 		 */
-#ifdef REAL_DMA
 		atari_dma_residual = 0;
 		atari_dma_active = 0;
 		atari_dma_stram_mask = (ATARIHW_PRESENT(EXTD_DMA) ? 0x00000000
 					: 0xff000000);
-#endif
 	}
 
 	NCR5380_maybe_reset_bus(instance);
Index: linux/drivers/scsi/sun3_scsi.c
===================================================================
--- linux.orig/drivers/scsi/sun3_scsi.c	2016-03-23 21:05:16.000000000 +1100
+++ linux/drivers/scsi/sun3_scsi.c	2016-03-23 21:09:22.000000000 +1100
@@ -38,7 +38,6 @@
 
 /* Definitions for the core NCR5380 driver. */
 
-#define REAL_DMA
 /* #define SUPPORT_TAGS */
 /* minimum number of bytes to do dma on */
 #define DMA_MIN_SIZE                    129
@@ -527,15 +526,9 @@ static int __init sun3_scsi_probe(struct
 	error = request_irq(instance->irq, scsi_sun3_intr, 0,
 	                    "NCR5380", instance);
 	if (error) {
-#ifdef REAL_DMA
 		pr_err(PFX "scsi%d: IRQ %d not free, bailing out\n",
 		       instance->host_no, instance->irq);
 		goto fail_irq;
-#else
-		pr_warn(PFX "scsi%d: IRQ %d not free, interrupts disabled\n",
-		        instance->host_no, instance->irq);
-		instance->irq = NO_IRQ;
-#endif
 	}
 
 	dregs->csr = 0;
@@ -565,8 +558,7 @@ static int __init sun3_scsi_probe(struct
 	return 0;
 
 fail_host:
-	if (instance->irq != NO_IRQ)
-		free_irq(instance->irq, instance);
+	free_irq(instance->irq, instance);
 fail_irq:
 	NCR5380_exit(instance);
 fail_init:
@@ -583,8 +575,7 @@ static int __exit sun3_scsi_remove(struc
 	struct Scsi_Host *instance = platform_get_drvdata(pdev);
 
 	scsi_remove_host(instance);
-	if (instance->irq != NO_IRQ)
-		free_irq(instance->irq, instance);
+	free_irq(instance->irq, instance);
 	NCR5380_exit(instance);
 	scsi_host_put(instance);
 	if (udc_regs)



^ permalink raw reply	[flat|nested] 60+ messages in thread

* [PATCH v4 04/23] atari_NCR5380: Remove DMA_MIN_SIZE macro
  2016-03-23 10:10 ` Finn Thain
@ 2016-03-23 10:10   ` Finn Thain
  -1 siblings, 0 replies; 60+ messages in thread
From: Finn Thain @ 2016-03-23 10:10 UTC (permalink / raw)
  To: James E.J. Bottomley, Martin K. Petersen, Michael Schmitz,
	linux-m68k, linux-scsi, linux-kernel
  Cc: Ondrej Zary, Sam Creasey

[-- Attachment #1: atari_NCR5380-remove-DMA_MIN_SIZE-macro --]
[-- Type: text/plain, Size: 4865 bytes --]

Only the atari_scsi and sun3_scsi drivers define DMA_MIN_SIZE.
Both drivers also define NCR5380_dma_xfer_len, which means
DMA_MIN_SIZE can be removed from the core driver.

This removes another discrepancy between the two core drivers.

Signed-off-by: Finn Thain <fthain@telegraphics.com.au>
Tested-by: Michael Schmitz <schmitzmic@gmail.com>
Reviewed-by: Hannes Reinecke <hare@suse.com>

---

Changes since v1:
- Retain MIN_DMA_SIZE macro in wrapper drivers.

---
 drivers/scsi/atari_NCR5380.c |   16 ++++++++--------
 drivers/scsi/atari_scsi.c    |    6 +++++-
 drivers/scsi/sun3_scsi.c     |   19 +++++++++----------
 3 files changed, 22 insertions(+), 19 deletions(-)

Index: linux/drivers/scsi/atari_NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/atari_NCR5380.c	2016-03-23 21:09:22.000000000 +1100
+++ linux/drivers/scsi/atari_NCR5380.c	2016-03-23 21:09:24.000000000 +1100
@@ -1857,12 +1857,11 @@ static void NCR5380_information_transfer
 					d = cmd->SCp.ptr;
 				}
 				/* this command setup for dma yet? */
-				if ((count >= DMA_MIN_SIZE) && (sun3_dma_setup_done != cmd)) {
-					if (cmd->request->cmd_type == REQ_TYPE_FS) {
-						sun3scsi_dma_setup(instance, d, count,
-						                   rq_data_dir(cmd->request));
-						sun3_dma_setup_done = cmd;
-					}
+				if (sun3_dma_setup_done != cmd &&
+				    sun3scsi_dma_xfer_len(count, cmd) > 0) {
+					sun3scsi_dma_setup(instance, d, count,
+					                   rq_data_dir(cmd->request));
+					sun3_dma_setup_done = cmd;
 				}
 #ifdef SUN3_SCSI_VME
 				dregs->csr |= CSR_INTR;
@@ -1927,7 +1926,7 @@ static void NCR5380_information_transfer
 #endif
 					transfersize = NCR5380_dma_xfer_len(instance, cmd, phase);
 
-				if (transfersize >= DMA_MIN_SIZE) {
+				if (transfersize > 0) {
 					len = transfersize;
 					cmd->SCp.phase = phase;
 					if (NCR5380_transfer_dma(instance, &phase,
@@ -2366,7 +2365,8 @@ static void NCR5380_reselect(struct Scsi
 			d = tmp->SCp.ptr;
 		}
 		/* setup this command for dma if not already */
-		if ((count >= DMA_MIN_SIZE) && (sun3_dma_setup_done != tmp)) {
+		if (sun3_dma_setup_done != tmp &&
+		    sun3scsi_dma_xfer_len(count, tmp) > 0) {
 			sun3scsi_dma_setup(instance, d, count,
 			                   rq_data_dir(tmp->request));
 			sun3_dma_setup_done = tmp;
Index: linux/drivers/scsi/atari_scsi.c
===================================================================
--- linux.orig/drivers/scsi/atari_scsi.c	2016-03-23 21:09:22.000000000 +1100
+++ linux/drivers/scsi/atari_scsi.c	2016-03-23 21:09:24.000000000 +1100
@@ -83,11 +83,12 @@
 
 #include <scsi/scsi_host.h>
 
+#define DMA_MIN_SIZE                    32
+
 /* Definitions for the core NCR5380 driver. */
 
 #define SUPPORT_TAGS
 #define MAX_TAGS                        32
-#define DMA_MIN_SIZE                    32
 
 #define NCR5380_implementation_fields   /* none */
 
@@ -605,6 +606,9 @@ static unsigned long atari_dma_xfer_len(
 {
 	unsigned long	possible_len, limit;
 
+	if (wanted_len < DMA_MIN_SIZE)
+		return 0;
+
 	if (IS_A_TT())
 		/* TT SCSI DMA can transfer arbitrary #bytes */
 		return wanted_len;
Index: linux/drivers/scsi/sun3_scsi.c
===================================================================
--- linux.orig/drivers/scsi/sun3_scsi.c	2016-03-23 21:09:22.000000000 +1100
+++ linux/drivers/scsi/sun3_scsi.c	2016-03-23 21:09:24.000000000 +1100
@@ -36,12 +36,12 @@
 #include <scsi/scsi_host.h>
 #include "sun3_scsi.h"
 
-/* Definitions for the core NCR5380 driver. */
-
-/* #define SUPPORT_TAGS */
 /* minimum number of bytes to do dma on */
 #define DMA_MIN_SIZE                    129
 
+/* Definitions for the core NCR5380 driver. */
+
+/* #define SUPPORT_TAGS */
 /* #define MAX_TAGS                     32 */
 
 #define NCR5380_implementation_fields   /* none */
@@ -61,7 +61,7 @@
 #define NCR5380_dma_residual(instance) \
         sun3scsi_dma_residual(instance)
 #define NCR5380_dma_xfer_len(instance, cmd, phase) \
-        sun3scsi_dma_xfer_len(cmd->SCp.this_residual, cmd, !((phase) & SR_IO))
+        sun3scsi_dma_xfer_len(cmd->SCp.this_residual, cmd)
 
 #define NCR5380_acquire_dma_irq(instance)    (1)
 #define NCR5380_release_dma_irq(instance)
@@ -262,14 +262,13 @@ static inline unsigned long sun3scsi_dma
 	return last_residual;
 }
 
-static inline unsigned long sun3scsi_dma_xfer_len(unsigned long wanted,
-						  struct scsi_cmnd *cmd,
-						  int write_flag)
+static inline unsigned long sun3scsi_dma_xfer_len(unsigned long wanted_len,
+                                                  struct scsi_cmnd *cmd)
 {
-	if (cmd->request->cmd_type == REQ_TYPE_FS)
- 		return wanted;
-	else
+	if (wanted_len < DMA_MIN_SIZE || cmd->request->cmd_type != REQ_TYPE_FS)
 		return 0;
+
+	return wanted_len;
 }
 
 static inline int sun3scsi_dma_start(unsigned long count, unsigned char *data)

^ permalink raw reply	[flat|nested] 60+ messages in thread

* [PATCH v4 04/23] atari_NCR5380: Remove DMA_MIN_SIZE macro
@ 2016-03-23 10:10   ` Finn Thain
  0 siblings, 0 replies; 60+ messages in thread
From: Finn Thain @ 2016-03-23 10:10 UTC (permalink / raw)
  To: James E.J. Bottomley, Martin K. Petersen, Michael Schmitz,
	linux-m68k, linux-scsi, linux-kernel
  Cc: Ondrej Zary, Sam Creasey

[-- Attachment #1: atari_NCR5380-remove-DMA_MIN_SIZE-macro --]
[-- Type: text/plain, Size: 4865 bytes --]

Only the atari_scsi and sun3_scsi drivers define DMA_MIN_SIZE.
Both drivers also define NCR5380_dma_xfer_len, which means
DMA_MIN_SIZE can be removed from the core driver.

This removes another discrepancy between the two core drivers.

Signed-off-by: Finn Thain <fthain@telegraphics.com.au>
Tested-by: Michael Schmitz <schmitzmic@gmail.com>
Reviewed-by: Hannes Reinecke <hare@suse.com>

---

Changes since v1:
- Retain MIN_DMA_SIZE macro in wrapper drivers.

---
 drivers/scsi/atari_NCR5380.c |   16 ++++++++--------
 drivers/scsi/atari_scsi.c    |    6 +++++-
 drivers/scsi/sun3_scsi.c     |   19 +++++++++----------
 3 files changed, 22 insertions(+), 19 deletions(-)

Index: linux/drivers/scsi/atari_NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/atari_NCR5380.c	2016-03-23 21:09:22.000000000 +1100
+++ linux/drivers/scsi/atari_NCR5380.c	2016-03-23 21:09:24.000000000 +1100
@@ -1857,12 +1857,11 @@ static void NCR5380_information_transfer
 					d = cmd->SCp.ptr;
 				}
 				/* this command setup for dma yet? */
-				if ((count >= DMA_MIN_SIZE) && (sun3_dma_setup_done != cmd)) {
-					if (cmd->request->cmd_type == REQ_TYPE_FS) {
-						sun3scsi_dma_setup(instance, d, count,
-						                   rq_data_dir(cmd->request));
-						sun3_dma_setup_done = cmd;
-					}
+				if (sun3_dma_setup_done != cmd &&
+				    sun3scsi_dma_xfer_len(count, cmd) > 0) {
+					sun3scsi_dma_setup(instance, d, count,
+					                   rq_data_dir(cmd->request));
+					sun3_dma_setup_done = cmd;
 				}
 #ifdef SUN3_SCSI_VME
 				dregs->csr |= CSR_INTR;
@@ -1927,7 +1926,7 @@ static void NCR5380_information_transfer
 #endif
 					transfersize = NCR5380_dma_xfer_len(instance, cmd, phase);
 
-				if (transfersize >= DMA_MIN_SIZE) {
+				if (transfersize > 0) {
 					len = transfersize;
 					cmd->SCp.phase = phase;
 					if (NCR5380_transfer_dma(instance, &phase,
@@ -2366,7 +2365,8 @@ static void NCR5380_reselect(struct Scsi
 			d = tmp->SCp.ptr;
 		}
 		/* setup this command for dma if not already */
-		if ((count >= DMA_MIN_SIZE) && (sun3_dma_setup_done != tmp)) {
+		if (sun3_dma_setup_done != tmp &&
+		    sun3scsi_dma_xfer_len(count, tmp) > 0) {
 			sun3scsi_dma_setup(instance, d, count,
 			                   rq_data_dir(tmp->request));
 			sun3_dma_setup_done = tmp;
Index: linux/drivers/scsi/atari_scsi.c
===================================================================
--- linux.orig/drivers/scsi/atari_scsi.c	2016-03-23 21:09:22.000000000 +1100
+++ linux/drivers/scsi/atari_scsi.c	2016-03-23 21:09:24.000000000 +1100
@@ -83,11 +83,12 @@
 
 #include <scsi/scsi_host.h>
 
+#define DMA_MIN_SIZE                    32
+
 /* Definitions for the core NCR5380 driver. */
 
 #define SUPPORT_TAGS
 #define MAX_TAGS                        32
-#define DMA_MIN_SIZE                    32
 
 #define NCR5380_implementation_fields   /* none */
 
@@ -605,6 +606,9 @@ static unsigned long atari_dma_xfer_len(
 {
 	unsigned long	possible_len, limit;
 
+	if (wanted_len < DMA_MIN_SIZE)
+		return 0;
+
 	if (IS_A_TT())
 		/* TT SCSI DMA can transfer arbitrary #bytes */
 		return wanted_len;
Index: linux/drivers/scsi/sun3_scsi.c
===================================================================
--- linux.orig/drivers/scsi/sun3_scsi.c	2016-03-23 21:09:22.000000000 +1100
+++ linux/drivers/scsi/sun3_scsi.c	2016-03-23 21:09:24.000000000 +1100
@@ -36,12 +36,12 @@
 #include <scsi/scsi_host.h>
 #include "sun3_scsi.h"
 
-/* Definitions for the core NCR5380 driver. */
-
-/* #define SUPPORT_TAGS */
 /* minimum number of bytes to do dma on */
 #define DMA_MIN_SIZE                    129
 
+/* Definitions for the core NCR5380 driver. */
+
+/* #define SUPPORT_TAGS */
 /* #define MAX_TAGS                     32 */
 
 #define NCR5380_implementation_fields   /* none */
@@ -61,7 +61,7 @@
 #define NCR5380_dma_residual(instance) \
         sun3scsi_dma_residual(instance)
 #define NCR5380_dma_xfer_len(instance, cmd, phase) \
-        sun3scsi_dma_xfer_len(cmd->SCp.this_residual, cmd, !((phase) & SR_IO))
+        sun3scsi_dma_xfer_len(cmd->SCp.this_residual, cmd)
 
 #define NCR5380_acquire_dma_irq(instance)    (1)
 #define NCR5380_release_dma_irq(instance)
@@ -262,14 +262,13 @@ static inline unsigned long sun3scsi_dma
 	return last_residual;
 }
 
-static inline unsigned long sun3scsi_dma_xfer_len(unsigned long wanted,
-						  struct scsi_cmnd *cmd,
-						  int write_flag)
+static inline unsigned long sun3scsi_dma_xfer_len(unsigned long wanted_len,
+                                                  struct scsi_cmnd *cmd)
 {
-	if (cmd->request->cmd_type == REQ_TYPE_FS)
- 		return wanted;
-	else
+	if (wanted_len < DMA_MIN_SIZE || cmd->request->cmd_type != REQ_TYPE_FS)
 		return 0;
+
+	return wanted_len;
 }
 
 static inline int sun3scsi_dma_start(unsigned long count, unsigned char *data)

^ permalink raw reply	[flat|nested] 60+ messages in thread

* [PATCH v4 05/23] ncr5380: Disable the DMA errata workaround flag by default
  2016-03-23 10:10 ` Finn Thain
  (?)
@ 2016-03-23 10:10   ` Finn Thain
  -1 siblings, 0 replies; 60+ messages in thread
From: Finn Thain @ 2016-03-23 10:10 UTC (permalink / raw)
  To: James E.J. Bottomley, Martin K. Petersen, Michael Schmitz,
	linux-m68k, linux-scsi, linux-kernel, Russell King,
	linux-arm-kernel
  Cc: Ondrej Zary, Sam Creasey

[-- Attachment #1: ncr5380-FLAG_DMA_FIXUP --]
[-- Type: text/plain, Size: 7058 bytes --]

The only chip that needs the workarounds enabled is an early NMOS
device. That means that the common case is to disable them.

Unfortunately the sense of the flag is such that it has to be set
for the common case.

Rename the flag so that zero can be used to mean "no errata workarounds
needed". This simplifies the code.

Signed-off-by: Finn Thain <fthain@telegraphics.com.au>
Reviewed-by: Hannes Reinecke <hare@suse.com>
Tested-by: Michael Schmitz <schmitzmic@gmail.com>
Tested-by: Ondrej Zary <linux@rainbow-software.org>

---
 drivers/scsi/NCR5380.c      |   14 +++++++-------
 drivers/scsi/NCR5380.h      |    2 +-
 drivers/scsi/arm/cumana_1.c |    2 +-
 drivers/scsi/arm/oak.c      |    2 +-
 drivers/scsi/dtc.c          |    2 +-
 drivers/scsi/g_NCR5380.c    |    8 +-------
 drivers/scsi/pas16.c        |    2 +-
 drivers/scsi/t128.c         |    2 +-
 8 files changed, 14 insertions(+), 20 deletions(-)

Index: linux/drivers/scsi/NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/NCR5380.c	2016-03-23 21:09:22.000000000 +1100
+++ linux/drivers/scsi/NCR5380.c	2016-03-23 21:09:26.000000000 +1100
@@ -457,7 +457,7 @@ static void prepare_info(struct Scsi_Hos
 	         instance->base, instance->irq,
 	         instance->can_queue, instance->cmd_per_lun,
 	         instance->sg_tablesize, instance->this_id,
-	         hostdata->flags & FLAG_NO_DMA_FIXUP  ? "NO_DMA_FIXUP "  : "",
+	         hostdata->flags & FLAG_DMA_FIXUP     ? "DMA_FIXUP "     : "",
 	         hostdata->flags & FLAG_NO_PSEUDO_DMA ? "NO_PSEUDO_DMA " : "",
 	         hostdata->flags & FLAG_TOSHIBA_DELAY ? "TOSHIBA_DELAY "  : "",
 #ifdef AUTOPROBE_IRQ
@@ -1480,11 +1480,11 @@ static int NCR5380_transfer_dma(struct S
 	 * before the setting of DMA mode to after transfer of the last byte.
 	 */
 
-	if (hostdata->flags & FLAG_NO_DMA_FIXUP)
+	if (hostdata->flags & FLAG_DMA_FIXUP)
+		NCR5380_write(MODE_REG, MR_BASE | MR_DMA_MODE | MR_MONITOR_BSY);
+	else
 		NCR5380_write(MODE_REG, MR_BASE | MR_DMA_MODE | MR_MONITOR_BSY |
 		                        MR_ENABLE_EOP_INTR);
-	else
-		NCR5380_write(MODE_REG, MR_BASE | MR_DMA_MODE | MR_MONITOR_BSY);
 
 	dprintk(NDEBUG_DMA, "scsi%d : mode reg = 0x%X\n", instance->host_no, NCR5380_read(MODE_REG));
 
@@ -1540,8 +1540,8 @@ static int NCR5380_transfer_dma(struct S
 
 	if (p & SR_IO) {
 		foo = NCR5380_pread(instance, d,
-			hostdata->flags & FLAG_NO_DMA_FIXUP ? c : c - 1);
-		if (!foo && !(hostdata->flags & FLAG_NO_DMA_FIXUP)) {
+			hostdata->flags & FLAG_DMA_FIXUP ? c - 1 : c);
+		if (!foo && (hostdata->flags & FLAG_DMA_FIXUP)) {
 			/*
 			 * The workaround was to transfer fewer bytes than we
 			 * intended to with the pseudo-DMA read function, wait for
@@ -1571,7 +1571,7 @@ static int NCR5380_transfer_dma(struct S
 		}
 	} else {
 		foo = NCR5380_pwrite(instance, d, c);
-		if (!foo && !(hostdata->flags & FLAG_NO_DMA_FIXUP)) {
+		if (!foo && (hostdata->flags & FLAG_DMA_FIXUP)) {
 			/*
 			 * Wait for the last byte to be sent.  If REQ is being asserted for
 			 * the byte we're interested, we'll ACK it and it will go false.
Index: linux/drivers/scsi/NCR5380.h
===================================================================
--- linux.orig/drivers/scsi/NCR5380.h	2016-03-23 21:09:22.000000000 +1100
+++ linux/drivers/scsi/NCR5380.h	2016-03-23 21:09:26.000000000 +1100
@@ -220,7 +220,7 @@
 #define NO_IRQ		0
 #endif
 
-#define FLAG_NO_DMA_FIXUP		1	/* No DMA errata workarounds */
+#define FLAG_DMA_FIXUP			1	/* Use DMA errata workarounds */
 #define FLAG_NO_PSEUDO_DMA		8	/* Inhibit DMA */
 #define FLAG_LATE_DMA_SETUP		32	/* Setup NCR before DMA H/W */
 #define FLAG_TAGGED_QUEUING		64	/* as X3T9.2 spelled it */
Index: linux/drivers/scsi/dtc.c
===================================================================
--- linux.orig/drivers/scsi/dtc.c	2016-03-23 21:05:15.000000000 +1100
+++ linux/drivers/scsi/dtc.c	2016-03-23 21:09:26.000000000 +1100
@@ -229,7 +229,7 @@ found:
 		instance->base = addr;
 		((struct NCR5380_hostdata *)(instance)->hostdata)->base = base;
 
-		if (NCR5380_init(instance, FLAG_NO_DMA_FIXUP))
+		if (NCR5380_init(instance, 0))
 			goto out_unregister;
 
 		NCR5380_maybe_reset_bus(instance);
Index: linux/drivers/scsi/g_NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/g_NCR5380.c	2016-03-23 21:09:20.000000000 +1100
+++ linux/drivers/scsi/g_NCR5380.c	2016-03-23 21:09:26.000000000 +1100
@@ -348,23 +348,17 @@ static int __init generic_NCR5380_detect
 		flags = 0;
 		switch (overrides[current_override].board) {
 		case BOARD_NCR5380:
-			flags = FLAG_NO_PSEUDO_DMA;
-			break;
-		case BOARD_NCR53C400:
-			flags = FLAG_NO_DMA_FIXUP;
+			flags = FLAG_NO_PSEUDO_DMA | FLAG_DMA_FIXUP;
 			break;
 		case BOARD_NCR53C400A:
-			flags = FLAG_NO_DMA_FIXUP;
 			ports = ncr_53c400a_ports;
 			magic = ncr_53c400a_magic;
 			break;
 		case BOARD_HP_C2502:
-			flags = FLAG_NO_DMA_FIXUP;
 			ports = ncr_53c400a_ports;
 			magic = hp_c2502_magic;
 			break;
 		case BOARD_DTC3181E:
-			flags = FLAG_NO_DMA_FIXUP;
 			ports = dtc_3181e_ports;
 			magic = ncr_53c400a_magic;
 			break;
Index: linux/drivers/scsi/arm/cumana_1.c
===================================================================
--- linux.orig/drivers/scsi/arm/cumana_1.c	2016-03-23 21:05:15.000000000 +1100
+++ linux/drivers/scsi/arm/cumana_1.c	2016-03-23 21:09:26.000000000 +1100
@@ -239,7 +239,7 @@ static int cumanascsi1_probe(struct expa
 
 	host->irq = ec->irq;
 
-	ret = NCR5380_init(host, 0);
+	ret = NCR5380_init(host, FLAG_DMA_FIXUP);
 	if (ret)
 		goto out_unmap;
 
Index: linux/drivers/scsi/arm/oak.c
===================================================================
--- linux.orig/drivers/scsi/arm/oak.c	2016-03-23 21:05:15.000000000 +1100
+++ linux/drivers/scsi/arm/oak.c	2016-03-23 21:09:26.000000000 +1100
@@ -143,7 +143,7 @@ static int oakscsi_probe(struct expansio
 	host->irq = NO_IRQ;
 	host->n_io_port = 255;
 
-	ret = NCR5380_init(host, 0);
+	ret = NCR5380_init(host, FLAG_DMA_FIXUP);
 	if (ret)
 		goto out_unmap;
 
Index: linux/drivers/scsi/pas16.c
===================================================================
--- linux.orig/drivers/scsi/pas16.c	2016-03-23 21:05:15.000000000 +1100
+++ linux/drivers/scsi/pas16.c	2016-03-23 21:09:26.000000000 +1100
@@ -377,7 +377,7 @@ static int __init pas16_detect(struct sc
 		
 	instance->io_port = io_port;
 
-	if (NCR5380_init(instance, 0))
+	if (NCR5380_init(instance, FLAG_DMA_FIXUP))
 		goto out_unregister;
 
 	NCR5380_maybe_reset_bus(instance);
Index: linux/drivers/scsi/t128.c
===================================================================
--- linux.orig/drivers/scsi/t128.c	2016-03-23 21:05:15.000000000 +1100
+++ linux/drivers/scsi/t128.c	2016-03-23 21:09:26.000000000 +1100
@@ -210,7 +210,7 @@ found:
 	instance->base = base;
 	((struct NCR5380_hostdata *)instance->hostdata)->base = p;
 
-	if (NCR5380_init(instance, 0))
+	if (NCR5380_init(instance, FLAG_DMA_FIXUP))
 		goto out_unregister;
 
 	NCR5380_maybe_reset_bus(instance);

^ permalink raw reply	[flat|nested] 60+ messages in thread

* [PATCH v4 05/23] ncr5380: Disable the DMA errata workaround flag by default
@ 2016-03-23 10:10   ` Finn Thain
  0 siblings, 0 replies; 60+ messages in thread
From: Finn Thain @ 2016-03-23 10:10 UTC (permalink / raw)
  To: James E.J. Bottomley, Martin K. Petersen, Michael Schmitz,
	linux-m68k, linux-scsi, linux-kernel, Russell King,
	linux-arm-kernel
  Cc: Sam Creasey, Ondrej Zary

[-- Attachment #1: ncr5380-FLAG_DMA_FIXUP --]
[-- Type: text/plain, Size: 7058 bytes --]

The only chip that needs the workarounds enabled is an early NMOS
device. That means that the common case is to disable them.

Unfortunately the sense of the flag is such that it has to be set
for the common case.

Rename the flag so that zero can be used to mean "no errata workarounds
needed". This simplifies the code.

Signed-off-by: Finn Thain <fthain@telegraphics.com.au>
Reviewed-by: Hannes Reinecke <hare@suse.com>
Tested-by: Michael Schmitz <schmitzmic@gmail.com>
Tested-by: Ondrej Zary <linux@rainbow-software.org>

---
 drivers/scsi/NCR5380.c      |   14 +++++++-------
 drivers/scsi/NCR5380.h      |    2 +-
 drivers/scsi/arm/cumana_1.c |    2 +-
 drivers/scsi/arm/oak.c      |    2 +-
 drivers/scsi/dtc.c          |    2 +-
 drivers/scsi/g_NCR5380.c    |    8 +-------
 drivers/scsi/pas16.c        |    2 +-
 drivers/scsi/t128.c         |    2 +-
 8 files changed, 14 insertions(+), 20 deletions(-)

Index: linux/drivers/scsi/NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/NCR5380.c	2016-03-23 21:09:22.000000000 +1100
+++ linux/drivers/scsi/NCR5380.c	2016-03-23 21:09:26.000000000 +1100
@@ -457,7 +457,7 @@ static void prepare_info(struct Scsi_Hos
 	         instance->base, instance->irq,
 	         instance->can_queue, instance->cmd_per_lun,
 	         instance->sg_tablesize, instance->this_id,
-	         hostdata->flags & FLAG_NO_DMA_FIXUP  ? "NO_DMA_FIXUP "  : "",
+	         hostdata->flags & FLAG_DMA_FIXUP     ? "DMA_FIXUP "     : "",
 	         hostdata->flags & FLAG_NO_PSEUDO_DMA ? "NO_PSEUDO_DMA " : "",
 	         hostdata->flags & FLAG_TOSHIBA_DELAY ? "TOSHIBA_DELAY "  : "",
 #ifdef AUTOPROBE_IRQ
@@ -1480,11 +1480,11 @@ static int NCR5380_transfer_dma(struct S
 	 * before the setting of DMA mode to after transfer of the last byte.
 	 */
 
-	if (hostdata->flags & FLAG_NO_DMA_FIXUP)
+	if (hostdata->flags & FLAG_DMA_FIXUP)
+		NCR5380_write(MODE_REG, MR_BASE | MR_DMA_MODE | MR_MONITOR_BSY);
+	else
 		NCR5380_write(MODE_REG, MR_BASE | MR_DMA_MODE | MR_MONITOR_BSY |
 		                        MR_ENABLE_EOP_INTR);
-	else
-		NCR5380_write(MODE_REG, MR_BASE | MR_DMA_MODE | MR_MONITOR_BSY);
 
 	dprintk(NDEBUG_DMA, "scsi%d : mode reg = 0x%X\n", instance->host_no, NCR5380_read(MODE_REG));
 
@@ -1540,8 +1540,8 @@ static int NCR5380_transfer_dma(struct S
 
 	if (p & SR_IO) {
 		foo = NCR5380_pread(instance, d,
-			hostdata->flags & FLAG_NO_DMA_FIXUP ? c : c - 1);
-		if (!foo && !(hostdata->flags & FLAG_NO_DMA_FIXUP)) {
+			hostdata->flags & FLAG_DMA_FIXUP ? c - 1 : c);
+		if (!foo && (hostdata->flags & FLAG_DMA_FIXUP)) {
 			/*
 			 * The workaround was to transfer fewer bytes than we
 			 * intended to with the pseudo-DMA read function, wait for
@@ -1571,7 +1571,7 @@ static int NCR5380_transfer_dma(struct S
 		}
 	} else {
 		foo = NCR5380_pwrite(instance, d, c);
-		if (!foo && !(hostdata->flags & FLAG_NO_DMA_FIXUP)) {
+		if (!foo && (hostdata->flags & FLAG_DMA_FIXUP)) {
 			/*
 			 * Wait for the last byte to be sent.  If REQ is being asserted for
 			 * the byte we're interested, we'll ACK it and it will go false.
Index: linux/drivers/scsi/NCR5380.h
===================================================================
--- linux.orig/drivers/scsi/NCR5380.h	2016-03-23 21:09:22.000000000 +1100
+++ linux/drivers/scsi/NCR5380.h	2016-03-23 21:09:26.000000000 +1100
@@ -220,7 +220,7 @@
 #define NO_IRQ		0
 #endif
 
-#define FLAG_NO_DMA_FIXUP		1	/* No DMA errata workarounds */
+#define FLAG_DMA_FIXUP			1	/* Use DMA errata workarounds */
 #define FLAG_NO_PSEUDO_DMA		8	/* Inhibit DMA */
 #define FLAG_LATE_DMA_SETUP		32	/* Setup NCR before DMA H/W */
 #define FLAG_TAGGED_QUEUING		64	/* as X3T9.2 spelled it */
Index: linux/drivers/scsi/dtc.c
===================================================================
--- linux.orig/drivers/scsi/dtc.c	2016-03-23 21:05:15.000000000 +1100
+++ linux/drivers/scsi/dtc.c	2016-03-23 21:09:26.000000000 +1100
@@ -229,7 +229,7 @@ found:
 		instance->base = addr;
 		((struct NCR5380_hostdata *)(instance)->hostdata)->base = base;
 
-		if (NCR5380_init(instance, FLAG_NO_DMA_FIXUP))
+		if (NCR5380_init(instance, 0))
 			goto out_unregister;
 
 		NCR5380_maybe_reset_bus(instance);
Index: linux/drivers/scsi/g_NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/g_NCR5380.c	2016-03-23 21:09:20.000000000 +1100
+++ linux/drivers/scsi/g_NCR5380.c	2016-03-23 21:09:26.000000000 +1100
@@ -348,23 +348,17 @@ static int __init generic_NCR5380_detect
 		flags = 0;
 		switch (overrides[current_override].board) {
 		case BOARD_NCR5380:
-			flags = FLAG_NO_PSEUDO_DMA;
-			break;
-		case BOARD_NCR53C400:
-			flags = FLAG_NO_DMA_FIXUP;
+			flags = FLAG_NO_PSEUDO_DMA | FLAG_DMA_FIXUP;
 			break;
 		case BOARD_NCR53C400A:
-			flags = FLAG_NO_DMA_FIXUP;
 			ports = ncr_53c400a_ports;
 			magic = ncr_53c400a_magic;
 			break;
 		case BOARD_HP_C2502:
-			flags = FLAG_NO_DMA_FIXUP;
 			ports = ncr_53c400a_ports;
 			magic = hp_c2502_magic;
 			break;
 		case BOARD_DTC3181E:
-			flags = FLAG_NO_DMA_FIXUP;
 			ports = dtc_3181e_ports;
 			magic = ncr_53c400a_magic;
 			break;
Index: linux/drivers/scsi/arm/cumana_1.c
===================================================================
--- linux.orig/drivers/scsi/arm/cumana_1.c	2016-03-23 21:05:15.000000000 +1100
+++ linux/drivers/scsi/arm/cumana_1.c	2016-03-23 21:09:26.000000000 +1100
@@ -239,7 +239,7 @@ static int cumanascsi1_probe(struct expa
 
 	host->irq = ec->irq;
 
-	ret = NCR5380_init(host, 0);
+	ret = NCR5380_init(host, FLAG_DMA_FIXUP);
 	if (ret)
 		goto out_unmap;
 
Index: linux/drivers/scsi/arm/oak.c
===================================================================
--- linux.orig/drivers/scsi/arm/oak.c	2016-03-23 21:05:15.000000000 +1100
+++ linux/drivers/scsi/arm/oak.c	2016-03-23 21:09:26.000000000 +1100
@@ -143,7 +143,7 @@ static int oakscsi_probe(struct expansio
 	host->irq = NO_IRQ;
 	host->n_io_port = 255;
 
-	ret = NCR5380_init(host, 0);
+	ret = NCR5380_init(host, FLAG_DMA_FIXUP);
 	if (ret)
 		goto out_unmap;
 
Index: linux/drivers/scsi/pas16.c
===================================================================
--- linux.orig/drivers/scsi/pas16.c	2016-03-23 21:05:15.000000000 +1100
+++ linux/drivers/scsi/pas16.c	2016-03-23 21:09:26.000000000 +1100
@@ -377,7 +377,7 @@ static int __init pas16_detect(struct sc
 		
 	instance->io_port = io_port;
 
-	if (NCR5380_init(instance, 0))
+	if (NCR5380_init(instance, FLAG_DMA_FIXUP))
 		goto out_unregister;
 
 	NCR5380_maybe_reset_bus(instance);
Index: linux/drivers/scsi/t128.c
===================================================================
--- linux.orig/drivers/scsi/t128.c	2016-03-23 21:05:15.000000000 +1100
+++ linux/drivers/scsi/t128.c	2016-03-23 21:09:26.000000000 +1100
@@ -210,7 +210,7 @@ found:
 	instance->base = base;
 	((struct NCR5380_hostdata *)instance->hostdata)->base = p;
 
-	if (NCR5380_init(instance, 0))
+	if (NCR5380_init(instance, FLAG_DMA_FIXUP))
 		goto out_unregister;
 
 	NCR5380_maybe_reset_bus(instance);

^ permalink raw reply	[flat|nested] 60+ messages in thread

* [PATCH v4 05/23] ncr5380: Disable the DMA errata workaround flag by default
@ 2016-03-23 10:10   ` Finn Thain
  0 siblings, 0 replies; 60+ messages in thread
From: Finn Thain @ 2016-03-23 10:10 UTC (permalink / raw)
  To: linux-arm-kernel

An embedded and charset-unspecified text was scrubbed...
Name: ncr5380-FLAG_DMA_FIXUP
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20160323/2c0e87b3/attachment.ksh>

^ permalink raw reply	[flat|nested] 60+ messages in thread

* [PATCH v4 06/23] ncr5380: Remove PSEUDO_DMA macro
  2016-03-23 10:10 ` Finn Thain
  (?)
@ 2016-03-23 10:10   ` Finn Thain
  -1 siblings, 0 replies; 60+ messages in thread
From: Finn Thain @ 2016-03-23 10:10 UTC (permalink / raw)
  To: James E.J. Bottomley, Martin K. Petersen, Michael Schmitz,
	linux-m68k, linux-scsi, linux-kernel, Russell King,
	linux-arm-kernel
  Cc: Ondrej Zary, Sam Creasey

[-- Attachment #1: ncr5380-remove-PSEUDO_DMA-macro --]
[-- Type: text/plain, Size: 13416 bytes --]

For those wrapper drivers which only implement Programmed IO, have
NCR5380_dma_xfer_len() evaluate to zero. That allows PDMA to be easily
disabled at run-time and so the PSEUDO_DMA macro is no longer needed.

Also remove the spin counters used for debugging pseudo DMA drivers.

Signed-off-by: Finn Thain <fthain@telegraphics.com.au>
Reviewed-by: Hannes Reinecke <hare@suse.com>
Tested-by: Michael Schmitz <schmitzmic@gmail.com>
Tested-by: Ondrej Zary <linux@rainbow-software.org>

---
 drivers/scsi/NCR5380.c      |   32 +-------------------------------
 drivers/scsi/NCR5380.h      |    4 ----
 drivers/scsi/arm/cumana_1.c |    2 --
 drivers/scsi/arm/oak.c      |    3 +--
 drivers/scsi/dmx3191d.c     |    4 ++++
 drivers/scsi/dtc.c          |    7 -------
 drivers/scsi/dtc.h          |    2 --
 drivers/scsi/g_NCR5380.c    |    1 -
 drivers/scsi/g_NCR5380.h    |    1 -
 drivers/scsi/mac_scsi.c     |   10 ----------
 drivers/scsi/pas16.c        |   10 ----------
 drivers/scsi/pas16.h        |    2 --
 drivers/scsi/t128.c         |    4 ----
 drivers/scsi/t128.h         |    2 --
 14 files changed, 6 insertions(+), 78 deletions(-)

Index: linux/drivers/scsi/NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/NCR5380.c	2016-03-23 21:09:26.000000000 +1100
+++ linux/drivers/scsi/NCR5380.c	2016-03-23 21:09:28.000000000 +1100
@@ -469,34 +469,9 @@ static void prepare_info(struct Scsi_Hos
 #ifdef PARITY
 	         "PARITY "
 #endif
-#ifdef PSEUDO_DMA
-	         "PSEUDO_DMA "
-#endif
 	         "");
 }
 
-#ifdef PSEUDO_DMA
-static int __maybe_unused NCR5380_write_info(struct Scsi_Host *instance,
-	char *buffer, int length)
-{
-	struct NCR5380_hostdata *hostdata = shost_priv(instance);
-
-	hostdata->spin_max_r = 0;
-	hostdata->spin_max_w = 0;
-	return 0;
-}
-
-static int __maybe_unused NCR5380_show_info(struct seq_file *m,
-                                            struct Scsi_Host *instance)
-{
-	struct NCR5380_hostdata *hostdata = shost_priv(instance);
-
-	seq_printf(m, "Highwater I/O busy spin counts: write %d, read %d\n",
-	        hostdata->spin_max_w, hostdata->spin_max_r);
-	return 0;
-}
-#endif
-
 /**
  * NCR5380_init - initialise an NCR5380
  * @instance: adapter to configure
@@ -1436,7 +1411,6 @@ timeout:
 	return -1;
 }
 
-#if defined(PSEUDO_DMA)
 /*
  * Function : int NCR5380_transfer_dma (struct Scsi_Host *instance,
  * unsigned char *phase, int *count, unsigned char **data)
@@ -1592,7 +1566,6 @@ static int NCR5380_transfer_dma(struct S
 	*phase = NCR5380_read(STATUS_REG) & PHASE_MASK;
 	return foo;
 }
-#endif /* PSEUDO_DMA */
 
 /*
  * Function : NCR5380_information_transfer (struct Scsi_Host *instance)
@@ -1683,7 +1656,6 @@ static void NCR5380_information_transfer
 				 * in an unconditional loop.
 				 */
 
-#if defined(PSEUDO_DMA)
 				transfersize = 0;
 				if (!cmd->device->borken)
 					transfersize = NCR5380_dma_xfer_len(instance, cmd, phase);
@@ -1706,9 +1678,7 @@ static void NCR5380_information_transfer
 						/* XXX - need to source or sink data here, as appropriate */
 					} else
 						cmd->SCp.this_residual -= transfersize - len;
-				} else
-#endif /* PSEUDO_DMA */
-				{
+				} else {
 					/* Break up transfer into 3 ms chunks,
 					 * presuming 6 accesses per handshake.
 					 */
Index: linux/drivers/scsi/NCR5380.h
===================================================================
--- linux.orig/drivers/scsi/NCR5380.h	2016-03-23 21:09:26.000000000 +1100
+++ linux/drivers/scsi/NCR5380.h	2016-03-23 21:09:28.000000000 +1100
@@ -257,10 +257,6 @@ struct NCR5380_hostdata {
 #ifdef SUPPORT_TAGS
 	struct tag_alloc TagAlloc[8][8];	/* 8 targets and 8 LUNs */
 #endif
-#ifdef PSEUDO_DMA
-	unsigned spin_max_r;
-	unsigned spin_max_w;
-#endif
 	struct workqueue_struct *work_q;
 	unsigned long accesses_per_ms;	/* chip register accesses per ms */
 };
Index: linux/drivers/scsi/arm/cumana_1.c
===================================================================
--- linux.orig/drivers/scsi/arm/cumana_1.c	2016-03-23 21:09:26.000000000 +1100
+++ linux/drivers/scsi/arm/cumana_1.c	2016-03-23 21:09:28.000000000 +1100
@@ -13,8 +13,6 @@
 
 #include <scsi/scsi_host.h>
 
-#define PSEUDO_DMA
-
 #define priv(host)			((struct NCR5380_hostdata *)(host)->hostdata)
 #define NCR5380_read(reg)		cumanascsi_read(instance, reg)
 #define NCR5380_write(reg, value)	cumanascsi_write(instance, reg, value)
Index: linux/drivers/scsi/arm/oak.c
===================================================================
--- linux.orig/drivers/scsi/arm/oak.c	2016-03-23 21:09:26.000000000 +1100
+++ linux/drivers/scsi/arm/oak.c	2016-03-23 21:09:28.000000000 +1100
@@ -14,7 +14,6 @@
 
 #include <scsi/scsi_host.h>
 
-/*#define PSEUDO_DMA*/
 #define DONT_USE_INTR
 
 #define priv(host)			((struct NCR5380_hostdata *)(host)->hostdata)
@@ -24,7 +23,7 @@
 #define NCR5380_write(reg, value) \
 	writeb(value, priv(instance)->base + ((reg) << 2))
 
-#define NCR5380_dma_xfer_len(instance, cmd, phase)	(cmd->transfersize)
+#define NCR5380_dma_xfer_len(instance, cmd, phase)	(0)
 
 #define NCR5380_queue_command		oakscsi_queue_command
 #define NCR5380_info			oakscsi_info
Index: linux/drivers/scsi/dtc.c
===================================================================
--- linux.orig/drivers/scsi/dtc.c	2016-03-23 21:09:26.000000000 +1100
+++ linux/drivers/scsi/dtc.c	2016-03-23 21:09:28.000000000 +1100
@@ -1,4 +1,3 @@
-#define PSEUDO_DMA
 #define DONT_USE_INTR
 
 /*
@@ -352,8 +351,6 @@ static inline int NCR5380_pread(struct S
 	while (!(NCR5380_read(DTC_CONTROL_REG) & D_CR_ACCESS))
 		++i;
 	rtrc(0);
-	if (i > hostdata->spin_max_r)
-		hostdata->spin_max_r = i;
 	return (0);
 }
 
@@ -400,8 +397,6 @@ static inline int NCR5380_pwrite(struct
 	rtrc(7);
 	/* Check for parity error here. fixme. */
 	rtrc(0);
-	if (i > hostdata->spin_max_w)
-		hostdata->spin_max_w = i;
 	return (0);
 }
 
@@ -440,8 +435,6 @@ static struct scsi_host_template driver_
 	.detect			= dtc_detect,
 	.release		= dtc_release,
 	.proc_name		= "dtc3x80",
-	.show_info		= dtc_show_info,
-	.write_info		= dtc_write_info,
 	.info			= dtc_info,
 	.queuecommand		= dtc_queue_command,
 	.eh_abort_handler	= dtc_abort,
Index: linux/drivers/scsi/g_NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/g_NCR5380.c	2016-03-23 21:09:26.000000000 +1100
+++ linux/drivers/scsi/g_NCR5380.c	2016-03-23 21:09:28.000000000 +1100
@@ -57,7 +57,6 @@
  */
 
 #define AUTOPROBE_IRQ
-#define PSEUDO_DMA
 
 #include <asm/io.h>
 #include <linux/blkdev.h>
Index: linux/drivers/scsi/mac_scsi.c
===================================================================
--- linux.orig/drivers/scsi/mac_scsi.c	2016-03-23 21:09:20.000000000 +1100
+++ linux/drivers/scsi/mac_scsi.c	2016-03-23 21:09:28.000000000 +1100
@@ -28,8 +28,6 @@
 
 /* Definitions for the core NCR5380 driver. */
 
-#define PSEUDO_DMA
-
 #define NCR5380_implementation_fields   unsigned char *pdma_base
 
 #define NCR5380_read(reg)               macscsi_read(instance, reg)
@@ -46,8 +44,6 @@
 #define NCR5380_abort                   macscsi_abort
 #define NCR5380_bus_reset               macscsi_bus_reset
 #define NCR5380_info                    macscsi_info
-#define NCR5380_show_info               macscsi_show_info
-#define NCR5380_write_info              macscsi_write_info
 
 #include "NCR5380.h"
 
@@ -111,7 +107,6 @@ static int __init mac_scsi_setup(char *s
 __setup("mac5380=", mac_scsi_setup);
 #endif /* !MODULE */
 
-#ifdef PSEUDO_DMA
 /* 
    Pseudo-DMA: (Ove Edlund)
    The code attempts to catch bus errors that occur if one for example
@@ -303,7 +298,6 @@ static int macscsi_pwrite(struct Scsi_Ho
 
 	return 0;
 }
-#endif
 
 static int macscsi_dma_xfer_len(struct Scsi_Host *instance,
                                 struct scsi_cmnd *cmd)
@@ -324,8 +318,6 @@ static int macscsi_dma_xfer_len(struct S
 static struct scsi_host_template mac_scsi_template = {
 	.module			= THIS_MODULE,
 	.proc_name		= DRV_MODULE_NAME,
-	.show_info		= macscsi_show_info,
-	.write_info		= macscsi_write_info,
 	.name			= "Macintosh NCR5380 SCSI",
 	.info			= macscsi_info,
 	.queuecommand		= macscsi_queue_command,
@@ -351,9 +343,7 @@ static int __init mac_scsi_probe(struct
 	if (!pio_mem)
 		return -ENODEV;
 
-#ifdef PSEUDO_DMA
 	pdma_mem = platform_get_resource(pdev, IORESOURCE_MEM, 1);
-#endif
 
 	irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
 
Index: linux/drivers/scsi/pas16.c
===================================================================
--- linux.orig/drivers/scsi/pas16.c	2016-03-23 21:09:26.000000000 +1100
+++ linux/drivers/scsi/pas16.c	2016-03-23 21:09:28.000000000 +1100
@@ -1,5 +1,3 @@
-#define PSEUDO_DMA
-
 /*
  * This driver adapted from Drew Eckhardt's Trantor T128 driver
  *
@@ -479,7 +477,6 @@ static inline int NCR5380_pread (struct
 	P_DATA_REG_OFFSET);
     register int i = len;
     int ii = 0;
-    struct NCR5380_hostdata *hostdata = shost_priv(instance);
 
     while ( !(inb(instance->io_port + P_STATUS_REG_OFFSET) & P_ST_RDY) )
 	 ++ii;
@@ -492,8 +489,6 @@ static inline int NCR5380_pread (struct
 	    instance->host_no);
 	return -1;
     }
-    if (ii > hostdata->spin_max_r)
-        hostdata->spin_max_r = ii;
     return 0;
 }
 
@@ -516,7 +511,6 @@ static inline int NCR5380_pwrite (struct
     register unsigned short reg = (instance->io_port + P_DATA_REG_OFFSET);
     register int i = len;
     int ii = 0;
-    struct NCR5380_hostdata *hostdata = shost_priv(instance);
 
     while ( !((inb(instance->io_port + P_STATUS_REG_OFFSET)) & P_ST_RDY) )
 	 ++ii;
@@ -529,8 +523,6 @@ static inline int NCR5380_pwrite (struct
 	    instance->host_no);
 	return -1;
     }
-    if (ii > hostdata->spin_max_w)
-        hostdata->spin_max_w = ii;
     return 0;
 }
 
@@ -550,8 +542,6 @@ static struct scsi_host_template driver_
 	.detect			= pas16_detect,
 	.release		= pas16_release,
 	.proc_name		= "pas16",
-	.show_info		= pas16_show_info,
-	.write_info		= pas16_write_info,
 	.info			= pas16_info,
 	.queuecommand		= pas16_queue_command,
 	.eh_abort_handler	= pas16_abort,
Index: linux/drivers/scsi/t128.c
===================================================================
--- linux.orig/drivers/scsi/t128.c	2016-03-23 21:09:26.000000000 +1100
+++ linux/drivers/scsi/t128.c	2016-03-23 21:09:28.000000000 +1100
@@ -1,5 +1,3 @@
-#define PSEUDO_DMA
-
 /*
  * Trantor T128/T128F/T228 driver
  *	Note : architecturally, the T100 and T130 are different and won't 
@@ -394,8 +392,6 @@ static struct scsi_host_template driver_
 	.detect			= t128_detect,
 	.release		= t128_release,
 	.proc_name		= "t128",
-	.show_info		= t128_show_info,
-	.write_info		= t128_write_info,
 	.info			= t128_info,
 	.queuecommand		= t128_queue_command,
 	.eh_abort_handler	= t128_abort,
Index: linux/drivers/scsi/dmx3191d.c
===================================================================
--- linux.orig/drivers/scsi/dmx3191d.c	2016-03-23 21:09:20.000000000 +1100
+++ linux/drivers/scsi/dmx3191d.c	2016-03-23 21:09:28.000000000 +1100
@@ -39,6 +39,10 @@
 #define NCR5380_read(reg)		inb(instance->io_port + reg)
 #define NCR5380_write(reg, value)	outb(value, instance->io_port + reg)
 
+#define NCR5380_dma_xfer_len(instance, cmd, phase)	(0)
+#define NCR5380_pread(instance, dst, len)		(0)
+#define NCR5380_pwrite(instance, src, len)		(0)
+
 #define NCR5380_implementation_fields	/* none */
 
 #include "NCR5380.h"
Index: linux/drivers/scsi/dtc.h
===================================================================
--- linux.orig/drivers/scsi/dtc.h	2016-03-23 21:05:15.000000000 +1100
+++ linux/drivers/scsi/dtc.h	2016-03-23 21:09:28.000000000 +1100
@@ -27,8 +27,6 @@
 #define NCR5380_abort			dtc_abort
 #define NCR5380_bus_reset		dtc_bus_reset
 #define NCR5380_info			dtc_info
-#define NCR5380_show_info		dtc_show_info 
-#define NCR5380_write_info		dtc_write_info 
 
 /* 15 12 11 10
    1001 1100 0000 0000 */
Index: linux/drivers/scsi/g_NCR5380.h
===================================================================
--- linux.orig/drivers/scsi/g_NCR5380.h	2016-03-23 21:09:20.000000000 +1100
+++ linux/drivers/scsi/g_NCR5380.h	2016-03-23 21:09:28.000000000 +1100
@@ -70,7 +70,6 @@
 #define NCR5380_pread generic_NCR5380_pread
 #define NCR5380_pwrite generic_NCR5380_pwrite
 #define NCR5380_info generic_NCR5380_info
-#define NCR5380_show_info generic_NCR5380_show_info
 
 #define BOARD_NCR5380	0
 #define BOARD_NCR53C400	1
Index: linux/drivers/scsi/pas16.h
===================================================================
--- linux.orig/drivers/scsi/pas16.h	2016-03-23 21:05:15.000000000 +1100
+++ linux/drivers/scsi/pas16.h	2016-03-23 21:09:28.000000000 +1100
@@ -109,8 +109,6 @@
 #define NCR5380_abort pas16_abort
 #define NCR5380_bus_reset pas16_bus_reset
 #define NCR5380_info pas16_info
-#define NCR5380_show_info pas16_show_info
-#define NCR5380_write_info pas16_write_info
 
 /* 15 14 12 10 7 5 3 
    1101 0100 1010 1000 */
Index: linux/drivers/scsi/t128.h
===================================================================
--- linux.orig/drivers/scsi/t128.h	2016-03-23 21:05:15.000000000 +1100
+++ linux/drivers/scsi/t128.h	2016-03-23 21:09:28.000000000 +1100
@@ -83,8 +83,6 @@
 #define NCR5380_abort t128_abort
 #define NCR5380_bus_reset t128_bus_reset
 #define NCR5380_info t128_info
-#define NCR5380_show_info t128_show_info
-#define NCR5380_write_info t128_write_info
 
 /* 15 14 12 10 7 5 3
    1101 0100 1010 1000 */

^ permalink raw reply	[flat|nested] 60+ messages in thread

* [PATCH v4 06/23] ncr5380: Remove PSEUDO_DMA macro
@ 2016-03-23 10:10   ` Finn Thain
  0 siblings, 0 replies; 60+ messages in thread
From: Finn Thain @ 2016-03-23 10:10 UTC (permalink / raw)
  To: James E.J. Bottomley, Martin K. Petersen, Michael Schmitz,
	linux-m68k, linux-scsi, linux-kernel, Russell King,
	linux-arm-kernel
  Cc: Sam Creasey, Ondrej Zary

[-- Attachment #1: ncr5380-remove-PSEUDO_DMA-macro --]
[-- Type: text/plain, Size: 13416 bytes --]

For those wrapper drivers which only implement Programmed IO, have
NCR5380_dma_xfer_len() evaluate to zero. That allows PDMA to be easily
disabled at run-time and so the PSEUDO_DMA macro is no longer needed.

Also remove the spin counters used for debugging pseudo DMA drivers.

Signed-off-by: Finn Thain <fthain@telegraphics.com.au>
Reviewed-by: Hannes Reinecke <hare@suse.com>
Tested-by: Michael Schmitz <schmitzmic@gmail.com>
Tested-by: Ondrej Zary <linux@rainbow-software.org>

---
 drivers/scsi/NCR5380.c      |   32 +-------------------------------
 drivers/scsi/NCR5380.h      |    4 ----
 drivers/scsi/arm/cumana_1.c |    2 --
 drivers/scsi/arm/oak.c      |    3 +--
 drivers/scsi/dmx3191d.c     |    4 ++++
 drivers/scsi/dtc.c          |    7 -------
 drivers/scsi/dtc.h          |    2 --
 drivers/scsi/g_NCR5380.c    |    1 -
 drivers/scsi/g_NCR5380.h    |    1 -
 drivers/scsi/mac_scsi.c     |   10 ----------
 drivers/scsi/pas16.c        |   10 ----------
 drivers/scsi/pas16.h        |    2 --
 drivers/scsi/t128.c         |    4 ----
 drivers/scsi/t128.h         |    2 --
 14 files changed, 6 insertions(+), 78 deletions(-)

Index: linux/drivers/scsi/NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/NCR5380.c	2016-03-23 21:09:26.000000000 +1100
+++ linux/drivers/scsi/NCR5380.c	2016-03-23 21:09:28.000000000 +1100
@@ -469,34 +469,9 @@ static void prepare_info(struct Scsi_Hos
 #ifdef PARITY
 	         "PARITY "
 #endif
-#ifdef PSEUDO_DMA
-	         "PSEUDO_DMA "
-#endif
 	         "");
 }
 
-#ifdef PSEUDO_DMA
-static int __maybe_unused NCR5380_write_info(struct Scsi_Host *instance,
-	char *buffer, int length)
-{
-	struct NCR5380_hostdata *hostdata = shost_priv(instance);
-
-	hostdata->spin_max_r = 0;
-	hostdata->spin_max_w = 0;
-	return 0;
-}
-
-static int __maybe_unused NCR5380_show_info(struct seq_file *m,
-                                            struct Scsi_Host *instance)
-{
-	struct NCR5380_hostdata *hostdata = shost_priv(instance);
-
-	seq_printf(m, "Highwater I/O busy spin counts: write %d, read %d\n",
-	        hostdata->spin_max_w, hostdata->spin_max_r);
-	return 0;
-}
-#endif
-
 /**
  * NCR5380_init - initialise an NCR5380
  * @instance: adapter to configure
@@ -1436,7 +1411,6 @@ timeout:
 	return -1;
 }
 
-#if defined(PSEUDO_DMA)
 /*
  * Function : int NCR5380_transfer_dma (struct Scsi_Host *instance,
  * unsigned char *phase, int *count, unsigned char **data)
@@ -1592,7 +1566,6 @@ static int NCR5380_transfer_dma(struct S
 	*phase = NCR5380_read(STATUS_REG) & PHASE_MASK;
 	return foo;
 }
-#endif /* PSEUDO_DMA */
 
 /*
  * Function : NCR5380_information_transfer (struct Scsi_Host *instance)
@@ -1683,7 +1656,6 @@ static void NCR5380_information_transfer
 				 * in an unconditional loop.
 				 */
 
-#if defined(PSEUDO_DMA)
 				transfersize = 0;
 				if (!cmd->device->borken)
 					transfersize = NCR5380_dma_xfer_len(instance, cmd, phase);
@@ -1706,9 +1678,7 @@ static void NCR5380_information_transfer
 						/* XXX - need to source or sink data here, as appropriate */
 					} else
 						cmd->SCp.this_residual -= transfersize - len;
-				} else
-#endif /* PSEUDO_DMA */
-				{
+				} else {
 					/* Break up transfer into 3 ms chunks,
 					 * presuming 6 accesses per handshake.
 					 */
Index: linux/drivers/scsi/NCR5380.h
===================================================================
--- linux.orig/drivers/scsi/NCR5380.h	2016-03-23 21:09:26.000000000 +1100
+++ linux/drivers/scsi/NCR5380.h	2016-03-23 21:09:28.000000000 +1100
@@ -257,10 +257,6 @@ struct NCR5380_hostdata {
 #ifdef SUPPORT_TAGS
 	struct tag_alloc TagAlloc[8][8];	/* 8 targets and 8 LUNs */
 #endif
-#ifdef PSEUDO_DMA
-	unsigned spin_max_r;
-	unsigned spin_max_w;
-#endif
 	struct workqueue_struct *work_q;
 	unsigned long accesses_per_ms;	/* chip register accesses per ms */
 };
Index: linux/drivers/scsi/arm/cumana_1.c
===================================================================
--- linux.orig/drivers/scsi/arm/cumana_1.c	2016-03-23 21:09:26.000000000 +1100
+++ linux/drivers/scsi/arm/cumana_1.c	2016-03-23 21:09:28.000000000 +1100
@@ -13,8 +13,6 @@
 
 #include <scsi/scsi_host.h>
 
-#define PSEUDO_DMA
-
 #define priv(host)			((struct NCR5380_hostdata *)(host)->hostdata)
 #define NCR5380_read(reg)		cumanascsi_read(instance, reg)
 #define NCR5380_write(reg, value)	cumanascsi_write(instance, reg, value)
Index: linux/drivers/scsi/arm/oak.c
===================================================================
--- linux.orig/drivers/scsi/arm/oak.c	2016-03-23 21:09:26.000000000 +1100
+++ linux/drivers/scsi/arm/oak.c	2016-03-23 21:09:28.000000000 +1100
@@ -14,7 +14,6 @@
 
 #include <scsi/scsi_host.h>
 
-/*#define PSEUDO_DMA*/
 #define DONT_USE_INTR
 
 #define priv(host)			((struct NCR5380_hostdata *)(host)->hostdata)
@@ -24,7 +23,7 @@
 #define NCR5380_write(reg, value) \
 	writeb(value, priv(instance)->base + ((reg) << 2))
 
-#define NCR5380_dma_xfer_len(instance, cmd, phase)	(cmd->transfersize)
+#define NCR5380_dma_xfer_len(instance, cmd, phase)	(0)
 
 #define NCR5380_queue_command		oakscsi_queue_command
 #define NCR5380_info			oakscsi_info
Index: linux/drivers/scsi/dtc.c
===================================================================
--- linux.orig/drivers/scsi/dtc.c	2016-03-23 21:09:26.000000000 +1100
+++ linux/drivers/scsi/dtc.c	2016-03-23 21:09:28.000000000 +1100
@@ -1,4 +1,3 @@
-#define PSEUDO_DMA
 #define DONT_USE_INTR
 
 /*
@@ -352,8 +351,6 @@ static inline int NCR5380_pread(struct S
 	while (!(NCR5380_read(DTC_CONTROL_REG) & D_CR_ACCESS))
 		++i;
 	rtrc(0);
-	if (i > hostdata->spin_max_r)
-		hostdata->spin_max_r = i;
 	return (0);
 }
 
@@ -400,8 +397,6 @@ static inline int NCR5380_pwrite(struct
 	rtrc(7);
 	/* Check for parity error here. fixme. */
 	rtrc(0);
-	if (i > hostdata->spin_max_w)
-		hostdata->spin_max_w = i;
 	return (0);
 }
 
@@ -440,8 +435,6 @@ static struct scsi_host_template driver_
 	.detect			= dtc_detect,
 	.release		= dtc_release,
 	.proc_name		= "dtc3x80",
-	.show_info		= dtc_show_info,
-	.write_info		= dtc_write_info,
 	.info			= dtc_info,
 	.queuecommand		= dtc_queue_command,
 	.eh_abort_handler	= dtc_abort,
Index: linux/drivers/scsi/g_NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/g_NCR5380.c	2016-03-23 21:09:26.000000000 +1100
+++ linux/drivers/scsi/g_NCR5380.c	2016-03-23 21:09:28.000000000 +1100
@@ -57,7 +57,6 @@
  */
 
 #define AUTOPROBE_IRQ
-#define PSEUDO_DMA
 
 #include <asm/io.h>
 #include <linux/blkdev.h>
Index: linux/drivers/scsi/mac_scsi.c
===================================================================
--- linux.orig/drivers/scsi/mac_scsi.c	2016-03-23 21:09:20.000000000 +1100
+++ linux/drivers/scsi/mac_scsi.c	2016-03-23 21:09:28.000000000 +1100
@@ -28,8 +28,6 @@
 
 /* Definitions for the core NCR5380 driver. */
 
-#define PSEUDO_DMA
-
 #define NCR5380_implementation_fields   unsigned char *pdma_base
 
 #define NCR5380_read(reg)               macscsi_read(instance, reg)
@@ -46,8 +44,6 @@
 #define NCR5380_abort                   macscsi_abort
 #define NCR5380_bus_reset               macscsi_bus_reset
 #define NCR5380_info                    macscsi_info
-#define NCR5380_show_info               macscsi_show_info
-#define NCR5380_write_info              macscsi_write_info
 
 #include "NCR5380.h"
 
@@ -111,7 +107,6 @@ static int __init mac_scsi_setup(char *s
 __setup("mac5380=", mac_scsi_setup);
 #endif /* !MODULE */
 
-#ifdef PSEUDO_DMA
 /* 
    Pseudo-DMA: (Ove Edlund)
    The code attempts to catch bus errors that occur if one for example
@@ -303,7 +298,6 @@ static int macscsi_pwrite(struct Scsi_Ho
 
 	return 0;
 }
-#endif
 
 static int macscsi_dma_xfer_len(struct Scsi_Host *instance,
                                 struct scsi_cmnd *cmd)
@@ -324,8 +318,6 @@ static int macscsi_dma_xfer_len(struct S
 static struct scsi_host_template mac_scsi_template = {
 	.module			= THIS_MODULE,
 	.proc_name		= DRV_MODULE_NAME,
-	.show_info		= macscsi_show_info,
-	.write_info		= macscsi_write_info,
 	.name			= "Macintosh NCR5380 SCSI",
 	.info			= macscsi_info,
 	.queuecommand		= macscsi_queue_command,
@@ -351,9 +343,7 @@ static int __init mac_scsi_probe(struct
 	if (!pio_mem)
 		return -ENODEV;
 
-#ifdef PSEUDO_DMA
 	pdma_mem = platform_get_resource(pdev, IORESOURCE_MEM, 1);
-#endif
 
 	irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
 
Index: linux/drivers/scsi/pas16.c
===================================================================
--- linux.orig/drivers/scsi/pas16.c	2016-03-23 21:09:26.000000000 +1100
+++ linux/drivers/scsi/pas16.c	2016-03-23 21:09:28.000000000 +1100
@@ -1,5 +1,3 @@
-#define PSEUDO_DMA
-
 /*
  * This driver adapted from Drew Eckhardt's Trantor T128 driver
  *
@@ -479,7 +477,6 @@ static inline int NCR5380_pread (struct
 	P_DATA_REG_OFFSET);
     register int i = len;
     int ii = 0;
-    struct NCR5380_hostdata *hostdata = shost_priv(instance);
 
     while ( !(inb(instance->io_port + P_STATUS_REG_OFFSET) & P_ST_RDY) )
 	 ++ii;
@@ -492,8 +489,6 @@ static inline int NCR5380_pread (struct
 	    instance->host_no);
 	return -1;
     }
-    if (ii > hostdata->spin_max_r)
-        hostdata->spin_max_r = ii;
     return 0;
 }
 
@@ -516,7 +511,6 @@ static inline int NCR5380_pwrite (struct
     register unsigned short reg = (instance->io_port + P_DATA_REG_OFFSET);
     register int i = len;
     int ii = 0;
-    struct NCR5380_hostdata *hostdata = shost_priv(instance);
 
     while ( !((inb(instance->io_port + P_STATUS_REG_OFFSET)) & P_ST_RDY) )
 	 ++ii;
@@ -529,8 +523,6 @@ static inline int NCR5380_pwrite (struct
 	    instance->host_no);
 	return -1;
     }
-    if (ii > hostdata->spin_max_w)
-        hostdata->spin_max_w = ii;
     return 0;
 }
 
@@ -550,8 +542,6 @@ static struct scsi_host_template driver_
 	.detect			= pas16_detect,
 	.release		= pas16_release,
 	.proc_name		= "pas16",
-	.show_info		= pas16_show_info,
-	.write_info		= pas16_write_info,
 	.info			= pas16_info,
 	.queuecommand		= pas16_queue_command,
 	.eh_abort_handler	= pas16_abort,
Index: linux/drivers/scsi/t128.c
===================================================================
--- linux.orig/drivers/scsi/t128.c	2016-03-23 21:09:26.000000000 +1100
+++ linux/drivers/scsi/t128.c	2016-03-23 21:09:28.000000000 +1100
@@ -1,5 +1,3 @@
-#define PSEUDO_DMA
-
 /*
  * Trantor T128/T128F/T228 driver
  *	Note : architecturally, the T100 and T130 are different and won't 
@@ -394,8 +392,6 @@ static struct scsi_host_template driver_
 	.detect			= t128_detect,
 	.release		= t128_release,
 	.proc_name		= "t128",
-	.show_info		= t128_show_info,
-	.write_info		= t128_write_info,
 	.info			= t128_info,
 	.queuecommand		= t128_queue_command,
 	.eh_abort_handler	= t128_abort,
Index: linux/drivers/scsi/dmx3191d.c
===================================================================
--- linux.orig/drivers/scsi/dmx3191d.c	2016-03-23 21:09:20.000000000 +1100
+++ linux/drivers/scsi/dmx3191d.c	2016-03-23 21:09:28.000000000 +1100
@@ -39,6 +39,10 @@
 #define NCR5380_read(reg)		inb(instance->io_port + reg)
 #define NCR5380_write(reg, value)	outb(value, instance->io_port + reg)
 
+#define NCR5380_dma_xfer_len(instance, cmd, phase)	(0)
+#define NCR5380_pread(instance, dst, len)		(0)
+#define NCR5380_pwrite(instance, src, len)		(0)
+
 #define NCR5380_implementation_fields	/* none */
 
 #include "NCR5380.h"
Index: linux/drivers/scsi/dtc.h
===================================================================
--- linux.orig/drivers/scsi/dtc.h	2016-03-23 21:05:15.000000000 +1100
+++ linux/drivers/scsi/dtc.h	2016-03-23 21:09:28.000000000 +1100
@@ -27,8 +27,6 @@
 #define NCR5380_abort			dtc_abort
 #define NCR5380_bus_reset		dtc_bus_reset
 #define NCR5380_info			dtc_info
-#define NCR5380_show_info		dtc_show_info 
-#define NCR5380_write_info		dtc_write_info 
 
 /* 15 12 11 10
    1001 1100 0000 0000 */
Index: linux/drivers/scsi/g_NCR5380.h
===================================================================
--- linux.orig/drivers/scsi/g_NCR5380.h	2016-03-23 21:09:20.000000000 +1100
+++ linux/drivers/scsi/g_NCR5380.h	2016-03-23 21:09:28.000000000 +1100
@@ -70,7 +70,6 @@
 #define NCR5380_pread generic_NCR5380_pread
 #define NCR5380_pwrite generic_NCR5380_pwrite
 #define NCR5380_info generic_NCR5380_info
-#define NCR5380_show_info generic_NCR5380_show_info
 
 #define BOARD_NCR5380	0
 #define BOARD_NCR53C400	1
Index: linux/drivers/scsi/pas16.h
===================================================================
--- linux.orig/drivers/scsi/pas16.h	2016-03-23 21:05:15.000000000 +1100
+++ linux/drivers/scsi/pas16.h	2016-03-23 21:09:28.000000000 +1100
@@ -109,8 +109,6 @@
 #define NCR5380_abort pas16_abort
 #define NCR5380_bus_reset pas16_bus_reset
 #define NCR5380_info pas16_info
-#define NCR5380_show_info pas16_show_info
-#define NCR5380_write_info pas16_write_info
 
 /* 15 14 12 10 7 5 3 
    1101 0100 1010 1000 */
Index: linux/drivers/scsi/t128.h
===================================================================
--- linux.orig/drivers/scsi/t128.h	2016-03-23 21:05:15.000000000 +1100
+++ linux/drivers/scsi/t128.h	2016-03-23 21:09:28.000000000 +1100
@@ -83,8 +83,6 @@
 #define NCR5380_abort t128_abort
 #define NCR5380_bus_reset t128_bus_reset
 #define NCR5380_info t128_info
-#define NCR5380_show_info t128_show_info
-#define NCR5380_write_info t128_write_info
 
 /* 15 14 12 10 7 5 3
    1101 0100 1010 1000 */

^ permalink raw reply	[flat|nested] 60+ messages in thread

* [PATCH v4 06/23] ncr5380: Remove PSEUDO_DMA macro
@ 2016-03-23 10:10   ` Finn Thain
  0 siblings, 0 replies; 60+ messages in thread
From: Finn Thain @ 2016-03-23 10:10 UTC (permalink / raw)
  To: linux-arm-kernel

An embedded and charset-unspecified text was scrubbed...
Name: ncr5380-remove-PSEUDO_DMA-macro
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20160323/0230bb36/attachment.ksh>

^ permalink raw reply	[flat|nested] 60+ messages in thread

* [PATCH v4 07/23] ncr5380: Remove BOARD_REQUIRES_NO_DELAY macro
  2016-03-23 10:10 ` Finn Thain
@ 2016-03-23 10:10   ` Finn Thain
  -1 siblings, 0 replies; 60+ messages in thread
From: Finn Thain @ 2016-03-23 10:10 UTC (permalink / raw)
  To: James E.J. Bottomley, Martin K. Petersen, Michael Schmitz,
	linux-m68k, linux-scsi, linux-kernel
  Cc: Ondrej Zary, Sam Creasey

[-- Attachment #1: ncr5380-io_recovery_delay --]
[-- Type: text/plain, Size: 3177 bytes --]

The io_recovery_delay macro is intended to insert a microsecond delay
between the chip register accesses that begin a DMA operation. This
is reportedly needed for some ISA boards.

Reverse the sense of the macro test so that in the common case,
where no delay is required, drivers need not define the macro.

Signed-off-by: Finn Thain <fthain@telegraphics.com.au>
Reviewed-by: Hannes Reinecke <hare@suse.com>
Tested-by: Michael Schmitz <schmitzmic@gmail.com>
Tested-by: Ondrej Zary <linux@rainbow-software.org>

---
 drivers/scsi/NCR5380.c   |   18 ++++++++----------
 drivers/scsi/dtc.h       |    2 ++
 drivers/scsi/g_NCR5380.h |    2 ++
 drivers/scsi/t128.h      |    2 ++
 4 files changed, 14 insertions(+), 10 deletions(-)

Index: linux/drivers/scsi/NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/NCR5380.c	2016-03-23 21:09:28.000000000 +1100
+++ linux/drivers/scsi/NCR5380.c	2016-03-23 21:09:34.000000000 +1100
@@ -39,12 +39,6 @@
  * tagged queueing)
  */
 
-#ifdef BOARD_REQUIRES_NO_DELAY
-#define io_recovery_delay(x)
-#else
-#define io_recovery_delay(x)	udelay(x)
-#endif
-
 /*
  * Design
  *
@@ -150,6 +144,10 @@
  * possible) function may be used.
  */
 
+#ifndef NCR5380_io_delay
+#define NCR5380_io_delay(x)
+#endif
+
 static int do_abort(struct Scsi_Host *);
 static void do_reset(struct Scsi_Host *);
 
@@ -1468,14 +1466,14 @@ static int NCR5380_transfer_dma(struct S
 	 */
 
 	if (p & SR_IO) {
-		io_recovery_delay(1);
+		NCR5380_io_delay(1);
 		NCR5380_write(START_DMA_INITIATOR_RECEIVE_REG, 0);
 	} else {
-		io_recovery_delay(1);
+		NCR5380_io_delay(1);
 		NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_DATA);
-		io_recovery_delay(1);
+		NCR5380_io_delay(1);
 		NCR5380_write(START_DMA_SEND_REG, 0);
-		io_recovery_delay(1);
+		NCR5380_io_delay(1);
 	}
 
 /*
Index: linux/drivers/scsi/dtc.h
===================================================================
--- linux.orig/drivers/scsi/dtc.h	2016-03-23 21:09:28.000000000 +1100
+++ linux/drivers/scsi/dtc.h	2016-03-23 21:09:34.000000000 +1100
@@ -28,6 +28,8 @@
 #define NCR5380_bus_reset		dtc_bus_reset
 #define NCR5380_info			dtc_info
 
+#define NCR5380_io_delay(x)		udelay(x)
+
 /* 15 12 11 10
    1001 1100 0000 0000 */
 
Index: linux/drivers/scsi/g_NCR5380.h
===================================================================
--- linux.orig/drivers/scsi/g_NCR5380.h	2016-03-23 21:09:28.000000000 +1100
+++ linux/drivers/scsi/g_NCR5380.h	2016-03-23 21:09:34.000000000 +1100
@@ -71,6 +71,8 @@
 #define NCR5380_pwrite generic_NCR5380_pwrite
 #define NCR5380_info generic_NCR5380_info
 
+#define NCR5380_io_delay(x)		udelay(x)
+
 #define BOARD_NCR5380	0
 #define BOARD_NCR53C400	1
 #define BOARD_NCR53C400A 2
Index: linux/drivers/scsi/t128.h
===================================================================
--- linux.orig/drivers/scsi/t128.h	2016-03-23 21:09:28.000000000 +1100
+++ linux/drivers/scsi/t128.h	2016-03-23 21:09:34.000000000 +1100
@@ -84,6 +84,8 @@
 #define NCR5380_bus_reset t128_bus_reset
 #define NCR5380_info t128_info
 
+#define NCR5380_io_delay(x)		udelay(x)
+
 /* 15 14 12 10 7 5 3
    1101 0100 1010 1000 */
 

^ permalink raw reply	[flat|nested] 60+ messages in thread

* [PATCH v4 07/23] ncr5380: Remove BOARD_REQUIRES_NO_DELAY macro
@ 2016-03-23 10:10   ` Finn Thain
  0 siblings, 0 replies; 60+ messages in thread
From: Finn Thain @ 2016-03-23 10:10 UTC (permalink / raw)
  To: James E.J. Bottomley, Martin K. Petersen, Michael Schmitz,
	linux-m68k, linux-scsi, linux-kernel
  Cc: Ondrej Zary, Sam Creasey

[-- Attachment #1: ncr5380-io_recovery_delay --]
[-- Type: text/plain, Size: 3177 bytes --]

The io_recovery_delay macro is intended to insert a microsecond delay
between the chip register accesses that begin a DMA operation. This
is reportedly needed for some ISA boards.

Reverse the sense of the macro test so that in the common case,
where no delay is required, drivers need not define the macro.

Signed-off-by: Finn Thain <fthain@telegraphics.com.au>
Reviewed-by: Hannes Reinecke <hare@suse.com>
Tested-by: Michael Schmitz <schmitzmic@gmail.com>
Tested-by: Ondrej Zary <linux@rainbow-software.org>

---
 drivers/scsi/NCR5380.c   |   18 ++++++++----------
 drivers/scsi/dtc.h       |    2 ++
 drivers/scsi/g_NCR5380.h |    2 ++
 drivers/scsi/t128.h      |    2 ++
 4 files changed, 14 insertions(+), 10 deletions(-)

Index: linux/drivers/scsi/NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/NCR5380.c	2016-03-23 21:09:28.000000000 +1100
+++ linux/drivers/scsi/NCR5380.c	2016-03-23 21:09:34.000000000 +1100
@@ -39,12 +39,6 @@
  * tagged queueing)
  */
 
-#ifdef BOARD_REQUIRES_NO_DELAY
-#define io_recovery_delay(x)
-#else
-#define io_recovery_delay(x)	udelay(x)
-#endif
-
 /*
  * Design
  *
@@ -150,6 +144,10 @@
  * possible) function may be used.
  */
 
+#ifndef NCR5380_io_delay
+#define NCR5380_io_delay(x)
+#endif
+
 static int do_abort(struct Scsi_Host *);
 static void do_reset(struct Scsi_Host *);
 
@@ -1468,14 +1466,14 @@ static int NCR5380_transfer_dma(struct S
 	 */
 
 	if (p & SR_IO) {
-		io_recovery_delay(1);
+		NCR5380_io_delay(1);
 		NCR5380_write(START_DMA_INITIATOR_RECEIVE_REG, 0);
 	} else {
-		io_recovery_delay(1);
+		NCR5380_io_delay(1);
 		NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_DATA);
-		io_recovery_delay(1);
+		NCR5380_io_delay(1);
 		NCR5380_write(START_DMA_SEND_REG, 0);
-		io_recovery_delay(1);
+		NCR5380_io_delay(1);
 	}
 
 /*
Index: linux/drivers/scsi/dtc.h
===================================================================
--- linux.orig/drivers/scsi/dtc.h	2016-03-23 21:09:28.000000000 +1100
+++ linux/drivers/scsi/dtc.h	2016-03-23 21:09:34.000000000 +1100
@@ -28,6 +28,8 @@
 #define NCR5380_bus_reset		dtc_bus_reset
 #define NCR5380_info			dtc_info
 
+#define NCR5380_io_delay(x)		udelay(x)
+
 /* 15 12 11 10
    1001 1100 0000 0000 */
 
Index: linux/drivers/scsi/g_NCR5380.h
===================================================================
--- linux.orig/drivers/scsi/g_NCR5380.h	2016-03-23 21:09:28.000000000 +1100
+++ linux/drivers/scsi/g_NCR5380.h	2016-03-23 21:09:34.000000000 +1100
@@ -71,6 +71,8 @@
 #define NCR5380_pwrite generic_NCR5380_pwrite
 #define NCR5380_info generic_NCR5380_info
 
+#define NCR5380_io_delay(x)		udelay(x)
+
 #define BOARD_NCR5380	0
 #define BOARD_NCR53C400	1
 #define BOARD_NCR53C400A 2
Index: linux/drivers/scsi/t128.h
===================================================================
--- linux.orig/drivers/scsi/t128.h	2016-03-23 21:09:28.000000000 +1100
+++ linux/drivers/scsi/t128.h	2016-03-23 21:09:34.000000000 +1100
@@ -84,6 +84,8 @@
 #define NCR5380_bus_reset t128_bus_reset
 #define NCR5380_info t128_info
 
+#define NCR5380_io_delay(x)		udelay(x)
+
 /* 15 14 12 10 7 5 3
    1101 0100 1010 1000 */
 

^ permalink raw reply	[flat|nested] 60+ messages in thread

* [PATCH v4 08/23] ncr5380: Use DMA hooks for PDMA
  2016-03-23 10:10 ` Finn Thain
  (?)
@ 2016-03-23 10:10   ` Finn Thain
  -1 siblings, 0 replies; 60+ messages in thread
From: Finn Thain @ 2016-03-23 10:10 UTC (permalink / raw)
  To: James E.J. Bottomley, Martin K. Petersen, Michael Schmitz,
	linux-m68k, linux-scsi, linux-kernel, Russell King,
	linux-arm-kernel
  Cc: Ondrej Zary, Sam Creasey

[-- Attachment #1: ncr5380-rename-pread-and-pwrite --]
[-- Type: text/plain, Size: 15570 bytes --]

Those wrapper drivers which use DMA define the REAL_DMA macro and
those which use pseudo DMA define PSEUDO_DMA. These macros need to be
removed for a number of reasons, not least of which is to have drivers
share more code.

Redefine the PDMA send and receive hooks as DMA setup hooks, so that the
DMA code can be shared by all 5380 wrapper drivers. This will help to
reunify the forked core driver.

Signed-off-by: Finn Thain <fthain@telegraphics.com.au>
Reviewed-by: Hannes Reinecke <hare@suse.com>
Tested-by: Michael Schmitz <schmitzmic@gmail.com>
Tested-by: Ondrej Zary <linux@rainbow-software.org>

---
 drivers/scsi/NCR5380.c      |   10 ++--------
 drivers/scsi/arm/cumana_1.c |   10 ++++++----
 drivers/scsi/arm/oak.c      |   10 ++++++----
 drivers/scsi/dmx3191d.c     |    4 ++--
 drivers/scsi/dtc.c          |    6 ++++--
 drivers/scsi/dtc.h          |    2 ++
 drivers/scsi/g_NCR5380.c    |   10 ++++++----
 drivers/scsi/g_NCR5380.h    |    4 ++--
 drivers/scsi/mac_scsi.c     |    5 ++---
 drivers/scsi/pas16.c        |   14 ++++++++------
 drivers/scsi/pas16.h        |    2 ++
 drivers/scsi/t128.c         |   12 ++++++------
 drivers/scsi/t128.h         |    2 ++
 13 files changed, 50 insertions(+), 41 deletions(-)

Index: linux/drivers/scsi/NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/NCR5380.c	2016-03-23 21:09:34.000000000 +1100
+++ linux/drivers/scsi/NCR5380.c	2016-03-23 21:09:37.000000000 +1100
@@ -127,17 +127,11 @@
  * specific implementation of the NCR5380
  *
  * Either real DMA *or* pseudo DMA may be implemented
- * Note that the DMA setup functions should return the number of bytes
- * that they were able to program the controller for.
  *
  * NCR5380_dma_write_setup(instance, src, count) - initialize
  * NCR5380_dma_read_setup(instance, dst, count) - initialize
  * NCR5380_dma_residual(instance); - residual count
  *
- * PSEUDO functions :
- * NCR5380_pwrite(instance, src, count)
- * NCR5380_pread(instance, dst, count);
- *
  * The generic driver is initialized by calling NCR5380_init(instance),
  * after setting the appropriate host specific fields and ID.  If the
  * driver wishes to autoprobe for an IRQ line, the NCR5380_probe_irq(instance,
@@ -1511,7 +1505,7 @@ static int NCR5380_transfer_dma(struct S
  */
 
 	if (p & SR_IO) {
-		foo = NCR5380_pread(instance, d,
+		foo = NCR5380_dma_recv_setup(instance, d,
 			hostdata->flags & FLAG_DMA_FIXUP ? c - 1 : c);
 		if (!foo && (hostdata->flags & FLAG_DMA_FIXUP)) {
 			/*
@@ -1542,7 +1536,7 @@ static int NCR5380_transfer_dma(struct S
 			d[c - 1] = NCR5380_read(INPUT_DATA_REG);
 		}
 	} else {
-		foo = NCR5380_pwrite(instance, d, c);
+		foo = NCR5380_dma_send_setup(instance, d, c);
 		if (!foo && (hostdata->flags & FLAG_DMA_FIXUP)) {
 			/*
 			 * Wait for the last byte to be sent.  If REQ is being asserted for
Index: linux/drivers/scsi/arm/cumana_1.c
===================================================================
--- linux.orig/drivers/scsi/arm/cumana_1.c	2016-03-23 21:09:28.000000000 +1100
+++ linux/drivers/scsi/arm/cumana_1.c	2016-03-23 21:09:37.000000000 +1100
@@ -18,6 +18,8 @@
 #define NCR5380_write(reg, value)	cumanascsi_write(instance, reg, value)
 
 #define NCR5380_dma_xfer_len(instance, cmd, phase)	(cmd->transfersize)
+#define NCR5380_dma_recv_setup		cumanascsi_pread
+#define NCR5380_dma_send_setup		cumanascsi_pwrite
 
 #define NCR5380_intr			cumanascsi_intr
 #define NCR5380_queue_command		cumanascsi_queue_command
@@ -39,8 +41,8 @@ void cumanascsi_setup(char *str, int *in
 #define L(v)	(((v)<<16)|((v) & 0x0000ffff))
 #define H(v)	(((v)>>16)|((v) & 0xffff0000))
 
-static inline int
-NCR5380_pwrite(struct Scsi_Host *host, unsigned char *addr, int len)
+static inline int cumanascsi_pwrite(struct Scsi_Host *host,
+                                    unsigned char *addr, int len)
 {
   unsigned long *laddr;
   void __iomem *dma = priv(host)->dma + 0x2000;
@@ -102,8 +104,8 @@ end:
   return len;
 }
 
-static inline int
-NCR5380_pread(struct Scsi_Host *host, unsigned char *addr, int len)
+static inline int cumanascsi_pread(struct Scsi_Host *host,
+                                   unsigned char *addr, int len)
 {
   unsigned long *laddr;
   void __iomem *dma = priv(host)->dma + 0x2000;
Index: linux/drivers/scsi/arm/oak.c
===================================================================
--- linux.orig/drivers/scsi/arm/oak.c	2016-03-23 21:09:28.000000000 +1100
+++ linux/drivers/scsi/arm/oak.c	2016-03-23 21:09:37.000000000 +1100
@@ -24,6 +24,8 @@
 	writeb(value, priv(instance)->base + ((reg) << 2))
 
 #define NCR5380_dma_xfer_len(instance, cmd, phase)	(0)
+#define NCR5380_dma_recv_setup		oakscsi_pread
+#define NCR5380_dma_send_setup		oakscsi_pwrite
 
 #define NCR5380_queue_command		oakscsi_queue_command
 #define NCR5380_info			oakscsi_info
@@ -39,8 +41,8 @@
 #define STAT	((128 + 16) << 2)
 #define DATA	((128 + 8) << 2)
 
-static inline int NCR5380_pwrite(struct Scsi_Host *instance, unsigned char *addr,
-              int len)
+static inline int oakscsi_pwrite(struct Scsi_Host *instance,
+                                 unsigned char *addr, int len)
 {
   void __iomem *base = priv(instance)->base;
 
@@ -54,8 +56,8 @@ printk("writing %p len %d\n",addr, len);
   }
 }
 
-static inline int NCR5380_pread(struct Scsi_Host *instance, unsigned char *addr,
-              int len)
+static inline int oakscsi_pread(struct Scsi_Host *instance,
+                                unsigned char *addr, int len)
 {
   void __iomem *base = priv(instance)->base;
 printk("reading %p len %d\n", addr, len);
Index: linux/drivers/scsi/dtc.c
===================================================================
--- linux.orig/drivers/scsi/dtc.c	2016-03-23 21:09:28.000000000 +1100
+++ linux/drivers/scsi/dtc.c	2016-03-23 21:09:37.000000000 +1100
@@ -322,7 +322,8 @@ static int dtc_biosparam(struct scsi_dev
  * 	timeout.
 */
 
-static inline int NCR5380_pread(struct Scsi_Host *instance, unsigned char *dst, int len)
+static inline int dtc_pread(struct Scsi_Host *instance,
+                            unsigned char *dst, int len)
 {
 	unsigned char *d = dst;
 	int i;			/* For counting time spent in the poll-loop */
@@ -367,7 +368,8 @@ static inline int NCR5380_pread(struct S
  * 	timeout.
 */
 
-static inline int NCR5380_pwrite(struct Scsi_Host *instance, unsigned char *src, int len)
+static inline int dtc_pwrite(struct Scsi_Host *instance,
+                             unsigned char *src, int len)
 {
 	int i;
 	struct NCR5380_hostdata *hostdata = shost_priv(instance);
Index: linux/drivers/scsi/dtc.h
===================================================================
--- linux.orig/drivers/scsi/dtc.h	2016-03-23 21:09:34.000000000 +1100
+++ linux/drivers/scsi/dtc.h	2016-03-23 21:09:37.000000000 +1100
@@ -21,6 +21,8 @@
 
 #define NCR5380_dma_xfer_len(instance, cmd, phase) \
         dtc_dma_xfer_len(cmd)
+#define NCR5380_dma_recv_setup		dtc_pread
+#define NCR5380_dma_send_setup		dtc_pwrite
 
 #define NCR5380_intr			dtc_intr
 #define NCR5380_queue_command		dtc_queue_command
Index: linux/drivers/scsi/g_NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/g_NCR5380.c	2016-03-23 21:09:28.000000000 +1100
+++ linux/drivers/scsi/g_NCR5380.c	2016-03-23 21:09:37.000000000 +1100
@@ -551,7 +551,7 @@ static int generic_NCR5380_release_resou
 }
 
 /**
- *	NCR5380_pread		-	pseudo DMA read
+ *	generic_NCR5380_pread - pseudo DMA read
  *	@instance: adapter to read from
  *	@dst: buffer to read into
  *	@len: buffer length
@@ -560,7 +560,8 @@ static int generic_NCR5380_release_resou
  *	controller
  */
  
-static inline int NCR5380_pread(struct Scsi_Host *instance, unsigned char *dst, int len)
+static inline int generic_NCR5380_pread(struct Scsi_Host *instance,
+                                        unsigned char *dst, int len)
 {
 	struct NCR5380_hostdata *hostdata = shost_priv(instance);
 	int blocks = len / 128;
@@ -628,7 +629,7 @@ static inline int NCR5380_pread(struct S
 }
 
 /**
- *	NCR5380_write		-	pseudo DMA write
+ *	generic_NCR5380_pwrite - pseudo DMA write
  *	@instance: adapter to read from
  *	@dst: buffer to read into
  *	@len: buffer length
@@ -637,7 +638,8 @@ static inline int NCR5380_pread(struct S
  *	controller
  */
 
-static inline int NCR5380_pwrite(struct Scsi_Host *instance, unsigned char *src, int len)
+static inline int generic_NCR5380_pwrite(struct Scsi_Host *instance,
+                                         unsigned char *src, int len)
 {
 	struct NCR5380_hostdata *hostdata = shost_priv(instance);
 	int blocks = len / 128;
Index: linux/drivers/scsi/g_NCR5380.h
===================================================================
--- linux.orig/drivers/scsi/g_NCR5380.h	2016-03-23 21:09:34.000000000 +1100
+++ linux/drivers/scsi/g_NCR5380.h	2016-03-23 21:09:37.000000000 +1100
@@ -62,13 +62,13 @@
 
 #define NCR5380_dma_xfer_len(instance, cmd, phase) \
         generic_NCR5380_dma_xfer_len(instance, cmd)
+#define NCR5380_dma_recv_setup		generic_NCR5380_pread
+#define NCR5380_dma_send_setup		generic_NCR5380_pwrite
 
 #define NCR5380_intr generic_NCR5380_intr
 #define NCR5380_queue_command generic_NCR5380_queue_command
 #define NCR5380_abort generic_NCR5380_abort
 #define NCR5380_bus_reset generic_NCR5380_bus_reset
-#define NCR5380_pread generic_NCR5380_pread
-#define NCR5380_pwrite generic_NCR5380_pwrite
 #define NCR5380_info generic_NCR5380_info
 
 #define NCR5380_io_delay(x)		udelay(x)
Index: linux/drivers/scsi/mac_scsi.c
===================================================================
--- linux.orig/drivers/scsi/mac_scsi.c	2016-03-23 21:09:28.000000000 +1100
+++ linux/drivers/scsi/mac_scsi.c	2016-03-23 21:09:37.000000000 +1100
@@ -33,11 +33,10 @@
 #define NCR5380_read(reg)               macscsi_read(instance, reg)
 #define NCR5380_write(reg, value)       macscsi_write(instance, reg, value)
 
-#define NCR5380_pread                   macscsi_pread
-#define NCR5380_pwrite                  macscsi_pwrite
-
 #define NCR5380_dma_xfer_len(instance, cmd, phase) \
         macscsi_dma_xfer_len(instance, cmd)
+#define NCR5380_dma_recv_setup          macscsi_pread
+#define NCR5380_dma_send_setup          macscsi_pwrite
 
 #define NCR5380_intr                    macscsi_intr
 #define NCR5380_queue_command           macscsi_queue_command
Index: linux/drivers/scsi/pas16.c
===================================================================
--- linux.orig/drivers/scsi/pas16.c	2016-03-23 21:09:28.000000000 +1100
+++ linux/drivers/scsi/pas16.c	2016-03-23 21:09:37.000000000 +1100
@@ -458,7 +458,7 @@ static int pas16_biosparam(struct scsi_d
 }
 
 /*
- * Function : int NCR5380_pread (struct Scsi_Host *instance, 
+ * Function : int pas16_pread (struct Scsi_Host *instance,
  *	unsigned char *dst, int len)
  *
  * Purpose : Fast 5380 pseudo-dma read function, transfers len bytes to 
@@ -470,8 +470,9 @@ static int pas16_biosparam(struct scsi_d
  * 	timeout.
  */
 
-static inline int NCR5380_pread (struct Scsi_Host *instance, unsigned char *dst,
-    int len) {
+static inline int pas16_pread(struct Scsi_Host *instance,
+                              unsigned char *dst, int len)
+{
     register unsigned char  *d = dst;
     register unsigned short reg = (unsigned short) (instance->io_port + 
 	P_DATA_REG_OFFSET);
@@ -493,7 +494,7 @@ static inline int NCR5380_pread (struct
 }
 
 /*
- * Function : int NCR5380_pwrite (struct Scsi_Host *instance, 
+ * Function : int pas16_pwrite (struct Scsi_Host *instance,
  *	unsigned char *src, int len)
  *
  * Purpose : Fast 5380 pseudo-dma write function, transfers len bytes from
@@ -505,8 +506,9 @@ static inline int NCR5380_pread (struct
  * 	timeout.
  */
 
-static inline int NCR5380_pwrite (struct Scsi_Host *instance, unsigned char *src,
-    int len) {
+static inline int pas16_pwrite(struct Scsi_Host *instance,
+                               unsigned char *src, int len)
+{
     register unsigned char *s = src;
     register unsigned short reg = (instance->io_port + P_DATA_REG_OFFSET);
     register int i = len;
Index: linux/drivers/scsi/pas16.h
===================================================================
--- linux.orig/drivers/scsi/pas16.h	2016-03-23 21:09:28.000000000 +1100
+++ linux/drivers/scsi/pas16.h	2016-03-23 21:09:37.000000000 +1100
@@ -103,6 +103,8 @@
 #define NCR5380_write(reg, value) ( outb((value),PAS16_io_port(reg)) )
 
 #define NCR5380_dma_xfer_len(instance, cmd, phase)	(cmd->transfersize)
+#define NCR5380_dma_recv_setup		pas16_pread
+#define NCR5380_dma_send_setup		pas16_pwrite
 
 #define NCR5380_intr pas16_intr
 #define NCR5380_queue_command pas16_queue_command
Index: linux/drivers/scsi/t128.c
===================================================================
--- linux.orig/drivers/scsi/t128.c	2016-03-23 21:09:28.000000000 +1100
+++ linux/drivers/scsi/t128.c	2016-03-23 21:09:37.000000000 +1100
@@ -292,7 +292,7 @@ static int t128_biosparam(struct scsi_de
 }
 
 /*
- * Function : int NCR5380_pread (struct Scsi_Host *instance, 
+ * Function : int t128_pread (struct Scsi_Host *instance,
  *	unsigned char *dst, int len)
  *
  * Purpose : Fast 5380 pseudo-dma read function, transfers len bytes to 
@@ -304,8 +304,8 @@ static int t128_biosparam(struct scsi_de
  * 	timeout.
  */
 
-static inline int
-NCR5380_pread(struct Scsi_Host *instance, unsigned char *dst, int len)
+static inline int t128_pread(struct Scsi_Host *instance,
+                             unsigned char *dst, int len)
 {
 	struct NCR5380_hostdata *hostdata = shost_priv(instance);
 	void __iomem *reg, *base = hostdata->base;
@@ -338,7 +338,7 @@ NCR5380_pread(struct Scsi_Host *instance
 }
 
 /*
- * Function : int NCR5380_pwrite (struct Scsi_Host *instance, 
+ * Function : int t128_pwrite (struct Scsi_Host *instance,
  *	unsigned char *src, int len)
  *
  * Purpose : Fast 5380 pseudo-dma write function, transfers len bytes from
@@ -350,8 +350,8 @@ NCR5380_pread(struct Scsi_Host *instance
  * 	timeout.
  */
 
-static inline int
-NCR5380_pwrite(struct Scsi_Host *instance, unsigned char *src, int len)
+static inline int t128_pwrite(struct Scsi_Host *instance,
+                              unsigned char *src, int len)
 {
 	struct NCR5380_hostdata *hostdata = shost_priv(instance);
 	void __iomem *reg, *base = hostdata->base;
Index: linux/drivers/scsi/t128.h
===================================================================
--- linux.orig/drivers/scsi/t128.h	2016-03-23 21:09:34.000000000 +1100
+++ linux/drivers/scsi/t128.h	2016-03-23 21:09:37.000000000 +1100
@@ -77,6 +77,8 @@
 #define NCR5380_write(reg, value) writeb((value),(T128_address(reg)))
 
 #define NCR5380_dma_xfer_len(instance, cmd, phase)	(cmd->transfersize)
+#define NCR5380_dma_recv_setup		t128_pread
+#define NCR5380_dma_send_setup		t128_pwrite
 
 #define NCR5380_intr t128_intr
 #define NCR5380_queue_command t128_queue_command
Index: linux/drivers/scsi/dmx3191d.c
===================================================================
--- linux.orig/drivers/scsi/dmx3191d.c	2016-03-23 21:09:28.000000000 +1100
+++ linux/drivers/scsi/dmx3191d.c	2016-03-23 21:09:37.000000000 +1100
@@ -40,8 +40,8 @@
 #define NCR5380_write(reg, value)	outb(value, instance->io_port + reg)
 
 #define NCR5380_dma_xfer_len(instance, cmd, phase)	(0)
-#define NCR5380_pread(instance, dst, len)		(0)
-#define NCR5380_pwrite(instance, src, len)		(0)
+#define NCR5380_dma_recv_setup(instance, dst, len)	(0)
+#define NCR5380_dma_send_setup(instance, src, len)	(0)
 
 #define NCR5380_implementation_fields	/* none */
 

^ permalink raw reply	[flat|nested] 60+ messages in thread

* [PATCH v4 08/23] ncr5380: Use DMA hooks for PDMA
@ 2016-03-23 10:10   ` Finn Thain
  0 siblings, 0 replies; 60+ messages in thread
From: Finn Thain @ 2016-03-23 10:10 UTC (permalink / raw)
  To: James E.J. Bottomley, Martin K. Petersen, Michael Schmitz,
	linux-m68k, linux-scsi, linux-kernel, Russell King,
	linux-arm-kernel
  Cc: Sam Creasey, Ondrej Zary

[-- Attachment #1: ncr5380-rename-pread-and-pwrite --]
[-- Type: text/plain, Size: 15568 bytes --]

Those wrapper drivers which use DMA define the REAL_DMA macro and
those which use pseudo DMA define PSEUDO_DMA. These macros need to be
removed for a number of reasons, not least of which is to have drivers
share more code.

Redefine the PDMA send and receive hooks as DMA setup hooks, so that the
DMA code can be shared by all 5380 wrapper drivers. This will help to
reunify the forked core driver.

Signed-off-by: Finn Thain <fthain@telegraphics.com.au>
Reviewed-by: Hannes Reinecke <hare@suse.com>
Tested-by: Michael Schmitz <schmitzmic@gmail.com>
Tested-by: Ondrej Zary <linux@rainbow-software.org>

---
 drivers/scsi/NCR5380.c      |   10 ++--------
 drivers/scsi/arm/cumana_1.c |   10 ++++++----
 drivers/scsi/arm/oak.c      |   10 ++++++----
 drivers/scsi/dmx3191d.c     |    4 ++--
 drivers/scsi/dtc.c          |    6 ++++--
 drivers/scsi/dtc.h          |    2 ++
 drivers/scsi/g_NCR5380.c    |   10 ++++++----
 drivers/scsi/g_NCR5380.h    |    4 ++--
 drivers/scsi/mac_scsi.c     |    5 ++---
 drivers/scsi/pas16.c        |   14 ++++++++------
 drivers/scsi/pas16.h        |    2 ++
 drivers/scsi/t128.c         |   12 ++++++------
 drivers/scsi/t128.h         |    2 ++
 13 files changed, 50 insertions(+), 41 deletions(-)

Index: linux/drivers/scsi/NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/NCR5380.c	2016-03-23 21:09:34.000000000 +1100
+++ linux/drivers/scsi/NCR5380.c	2016-03-23 21:09:37.000000000 +1100
@@ -127,17 +127,11 @@
  * specific implementation of the NCR5380
  *
  * Either real DMA *or* pseudo DMA may be implemented
- * Note that the DMA setup functions should return the number of bytes
- * that they were able to program the controller for.
  *
  * NCR5380_dma_write_setup(instance, src, count) - initialize
  * NCR5380_dma_read_setup(instance, dst, count) - initialize
  * NCR5380_dma_residual(instance); - residual count
  *
- * PSEUDO functions :
- * NCR5380_pwrite(instance, src, count)
- * NCR5380_pread(instance, dst, count);
- *
  * The generic driver is initialized by calling NCR5380_init(instance),
  * after setting the appropriate host specific fields and ID.  If the
  * driver wishes to autoprobe for an IRQ line, the NCR5380_probe_irq(instance,
@@ -1511,7 +1505,7 @@ static int NCR5380_transfer_dma(struct S
  */
 
 	if (p & SR_IO) {
-		foo = NCR5380_pread(instance, d,
+		foo = NCR5380_dma_recv_setup(instance, d,
 			hostdata->flags & FLAG_DMA_FIXUP ? c - 1 : c);
 		if (!foo && (hostdata->flags & FLAG_DMA_FIXUP)) {
 			/*
@@ -1542,7 +1536,7 @@ static int NCR5380_transfer_dma(struct S
 			d[c - 1] = NCR5380_read(INPUT_DATA_REG);
 		}
 	} else {
-		foo = NCR5380_pwrite(instance, d, c);
+		foo = NCR5380_dma_send_setup(instance, d, c);
 		if (!foo && (hostdata->flags & FLAG_DMA_FIXUP)) {
 			/*
 			 * Wait for the last byte to be sent.  If REQ is being asserted for
Index: linux/drivers/scsi/arm/cumana_1.c
===================================================================
--- linux.orig/drivers/scsi/arm/cumana_1.c	2016-03-23 21:09:28.000000000 +1100
+++ linux/drivers/scsi/arm/cumana_1.c	2016-03-23 21:09:37.000000000 +1100
@@ -18,6 +18,8 @@
 #define NCR5380_write(reg, value)	cumanascsi_write(instance, reg, value)
 
 #define NCR5380_dma_xfer_len(instance, cmd, phase)	(cmd->transfersize)
+#define NCR5380_dma_recv_setup		cumanascsi_pread
+#define NCR5380_dma_send_setup		cumanascsi_pwrite
 
 #define NCR5380_intr			cumanascsi_intr
 #define NCR5380_queue_command		cumanascsi_queue_command
@@ -39,8 +41,8 @@ void cumanascsi_setup(char *str, int *in
 #define L(v)	(((v)<<16)|((v) & 0x0000ffff))
 #define H(v)	(((v)>>16)|((v) & 0xffff0000))
 
-static inline int
-NCR5380_pwrite(struct Scsi_Host *host, unsigned char *addr, int len)
+static inline int cumanascsi_pwrite(struct Scsi_Host *host,
+                                    unsigned char *addr, int len)
 {
   unsigned long *laddr;
   void __iomem *dma = priv(host)->dma + 0x2000;
@@ -102,8 +104,8 @@ end:
   return len;
 }
 
-static inline int
-NCR5380_pread(struct Scsi_Host *host, unsigned char *addr, int len)
+static inline int cumanascsi_pread(struct Scsi_Host *host,
+                                   unsigned char *addr, int len)
 {
   unsigned long *laddr;
   void __iomem *dma = priv(host)->dma + 0x2000;
Index: linux/drivers/scsi/arm/oak.c
===================================================================
--- linux.orig/drivers/scsi/arm/oak.c	2016-03-23 21:09:28.000000000 +1100
+++ linux/drivers/scsi/arm/oak.c	2016-03-23 21:09:37.000000000 +1100
@@ -24,6 +24,8 @@
 	writeb(value, priv(instance)->base + ((reg) << 2))
 
 #define NCR5380_dma_xfer_len(instance, cmd, phase)	(0)
+#define NCR5380_dma_recv_setup		oakscsi_pread
+#define NCR5380_dma_send_setup		oakscsi_pwrite
 
 #define NCR5380_queue_command		oakscsi_queue_command
 #define NCR5380_info			oakscsi_info
@@ -39,8 +41,8 @@
 #define STAT	((128 + 16) << 2)
 #define DATA	((128 + 8) << 2)
 
-static inline int NCR5380_pwrite(struct Scsi_Host *instance, unsigned char *addr,
-              int len)
+static inline int oakscsi_pwrite(struct Scsi_Host *instance,
+                                 unsigned char *addr, int len)
 {
   void __iomem *base = priv(instance)->base;
 
@@ -54,8 +56,8 @@ printk("writing %p len %d\n",addr, len);
   }
 }
 
-static inline int NCR5380_pread(struct Scsi_Host *instance, unsigned char *addr,
-              int len)
+static inline int oakscsi_pread(struct Scsi_Host *instance,
+                                unsigned char *addr, int len)
 {
   void __iomem *base = priv(instance)->base;
 printk("reading %p len %d\n", addr, len);
Index: linux/drivers/scsi/dtc.c
===================================================================
--- linux.orig/drivers/scsi/dtc.c	2016-03-23 21:09:28.000000000 +1100
+++ linux/drivers/scsi/dtc.c	2016-03-23 21:09:37.000000000 +1100
@@ -322,7 +322,8 @@ static int dtc_biosparam(struct scsi_dev
  * 	timeout.
 */
 
-static inline int NCR5380_pread(struct Scsi_Host *instance, unsigned char *dst, int len)
+static inline int dtc_pread(struct Scsi_Host *instance,
+                            unsigned char *dst, int len)
 {
 	unsigned char *d = dst;
 	int i;			/* For counting time spent in the poll-loop */
@@ -367,7 +368,8 @@ static inline int NCR5380_pread(struct S
  * 	timeout.
 */
 
-static inline int NCR5380_pwrite(struct Scsi_Host *instance, unsigned char *src, int len)
+static inline int dtc_pwrite(struct Scsi_Host *instance,
+                             unsigned char *src, int len)
 {
 	int i;
 	struct NCR5380_hostdata *hostdata = shost_priv(instance);
Index: linux/drivers/scsi/dtc.h
===================================================================
--- linux.orig/drivers/scsi/dtc.h	2016-03-23 21:09:34.000000000 +1100
+++ linux/drivers/scsi/dtc.h	2016-03-23 21:09:37.000000000 +1100
@@ -21,6 +21,8 @@
 
 #define NCR5380_dma_xfer_len(instance, cmd, phase) \
         dtc_dma_xfer_len(cmd)
+#define NCR5380_dma_recv_setup		dtc_pread
+#define NCR5380_dma_send_setup		dtc_pwrite
 
 #define NCR5380_intr			dtc_intr
 #define NCR5380_queue_command		dtc_queue_command
Index: linux/drivers/scsi/g_NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/g_NCR5380.c	2016-03-23 21:09:28.000000000 +1100
+++ linux/drivers/scsi/g_NCR5380.c	2016-03-23 21:09:37.000000000 +1100
@@ -551,7 +551,7 @@ static int generic_NCR5380_release_resou
 }
 
 /**
- *	NCR5380_pread		-	pseudo DMA read
+ *	generic_NCR5380_pread - pseudo DMA read
  *	@instance: adapter to read from
  *	@dst: buffer to read into
  *	@len: buffer length
@@ -560,7 +560,8 @@ static int generic_NCR5380_release_resou
  *	controller
  */
  
-static inline int NCR5380_pread(struct Scsi_Host *instance, unsigned char *dst, int len)
+static inline int generic_NCR5380_pread(struct Scsi_Host *instance,
+                                        unsigned char *dst, int len)
 {
 	struct NCR5380_hostdata *hostdata = shost_priv(instance);
 	int blocks = len / 128;
@@ -628,7 +629,7 @@ static inline int NCR5380_pread(struct S
 }
 
 /**
- *	NCR5380_write		-	pseudo DMA write
+ *	generic_NCR5380_pwrite - pseudo DMA write
  *	@instance: adapter to read from
  *	@dst: buffer to read into
  *	@len: buffer length
@@ -637,7 +638,8 @@ static inline int NCR5380_pread(struct S
  *	controller
  */
 
-static inline int NCR5380_pwrite(struct Scsi_Host *instance, unsigned char *src, int len)
+static inline int generic_NCR5380_pwrite(struct Scsi_Host *instance,
+                                         unsigned char *src, int len)
 {
 	struct NCR5380_hostdata *hostdata = shost_priv(instance);
 	int blocks = len / 128;
Index: linux/drivers/scsi/g_NCR5380.h
===================================================================
--- linux.orig/drivers/scsi/g_NCR5380.h	2016-03-23 21:09:34.000000000 +1100
+++ linux/drivers/scsi/g_NCR5380.h	2016-03-23 21:09:37.000000000 +1100
@@ -62,13 +62,13 @@
 
 #define NCR5380_dma_xfer_len(instance, cmd, phase) \
         generic_NCR5380_dma_xfer_len(instance, cmd)
+#define NCR5380_dma_recv_setup		generic_NCR5380_pread
+#define NCR5380_dma_send_setup		generic_NCR5380_pwrite
 
 #define NCR5380_intr generic_NCR5380_intr
 #define NCR5380_queue_command generic_NCR5380_queue_command
 #define NCR5380_abort generic_NCR5380_abort
 #define NCR5380_bus_reset generic_NCR5380_bus_reset
-#define NCR5380_pread generic_NCR5380_pread
-#define NCR5380_pwrite generic_NCR5380_pwrite
 #define NCR5380_info generic_NCR5380_info
 
 #define NCR5380_io_delay(x)		udelay(x)
Index: linux/drivers/scsi/mac_scsi.c
===================================================================
--- linux.orig/drivers/scsi/mac_scsi.c	2016-03-23 21:09:28.000000000 +1100
+++ linux/drivers/scsi/mac_scsi.c	2016-03-23 21:09:37.000000000 +1100
@@ -33,11 +33,10 @@
 #define NCR5380_read(reg)               macscsi_read(instance, reg)
 #define NCR5380_write(reg, value)       macscsi_write(instance, reg, value)
 
-#define NCR5380_pread                   macscsi_pread
-#define NCR5380_pwrite                  macscsi_pwrite
-
 #define NCR5380_dma_xfer_len(instance, cmd, phase) \
         macscsi_dma_xfer_len(instance, cmd)
+#define NCR5380_dma_recv_setup          macscsi_pread
+#define NCR5380_dma_send_setup          macscsi_pwrite
 
 #define NCR5380_intr                    macscsi_intr
 #define NCR5380_queue_command           macscsi_queue_command
Index: linux/drivers/scsi/pas16.c
===================================================================
--- linux.orig/drivers/scsi/pas16.c	2016-03-23 21:09:28.000000000 +1100
+++ linux/drivers/scsi/pas16.c	2016-03-23 21:09:37.000000000 +1100
@@ -458,7 +458,7 @@ static int pas16_biosparam(struct scsi_d
 }
 
 /*
- * Function : int NCR5380_pread (struct Scsi_Host *instance, 
+ * Function : int pas16_pread (struct Scsi_Host *instance,
  *	unsigned char *dst, int len)
  *
  * Purpose : Fast 5380 pseudo-dma read function, transfers len bytes to 
@@ -470,8 +470,9 @@ static int pas16_biosparam(struct scsi_d
  * 	timeout.
  */
 
-static inline int NCR5380_pread (struct Scsi_Host *instance, unsigned char *dst,
-    int len) {
+static inline int pas16_pread(struct Scsi_Host *instance,
+                              unsigned char *dst, int len)
+{
     register unsigned char  *d = dst;
     register unsigned short reg = (unsigned short) (instance->io_port + 
 	P_DATA_REG_OFFSET);
@@ -493,7 +494,7 @@ static inline int NCR5380_pread (struct
 }
 
 /*
- * Function : int NCR5380_pwrite (struct Scsi_Host *instance, 
+ * Function : int pas16_pwrite (struct Scsi_Host *instance,
  *	unsigned char *src, int len)
  *
  * Purpose : Fast 5380 pseudo-dma write function, transfers len bytes from
@@ -505,8 +506,9 @@ static inline int NCR5380_pread (struct
  * 	timeout.
  */
 
-static inline int NCR5380_pwrite (struct Scsi_Host *instance, unsigned char *src,
-    int len) {
+static inline int pas16_pwrite(struct Scsi_Host *instance,
+                               unsigned char *src, int len)
+{
     register unsigned char *s = src;
     register unsigned short reg = (instance->io_port + P_DATA_REG_OFFSET);
     register int i = len;
Index: linux/drivers/scsi/pas16.h
===================================================================
--- linux.orig/drivers/scsi/pas16.h	2016-03-23 21:09:28.000000000 +1100
+++ linux/drivers/scsi/pas16.h	2016-03-23 21:09:37.000000000 +1100
@@ -103,6 +103,8 @@
 #define NCR5380_write(reg, value) ( outb((value),PAS16_io_port(reg)) )
 
 #define NCR5380_dma_xfer_len(instance, cmd, phase)	(cmd->transfersize)
+#define NCR5380_dma_recv_setup		pas16_pread
+#define NCR5380_dma_send_setup		pas16_pwrite
 
 #define NCR5380_intr pas16_intr
 #define NCR5380_queue_command pas16_queue_command
Index: linux/drivers/scsi/t128.c
===================================================================
--- linux.orig/drivers/scsi/t128.c	2016-03-23 21:09:28.000000000 +1100
+++ linux/drivers/scsi/t128.c	2016-03-23 21:09:37.000000000 +1100
@@ -292,7 +292,7 @@ static int t128_biosparam(struct scsi_de
 }
 
 /*
- * Function : int NCR5380_pread (struct Scsi_Host *instance, 
+ * Function : int t128_pread (struct Scsi_Host *instance,
  *	unsigned char *dst, int len)
  *
  * Purpose : Fast 5380 pseudo-dma read function, transfers len bytes to 
@@ -304,8 +304,8 @@ static int t128_biosparam(struct scsi_de
  * 	timeout.
  */
 
-static inline int
-NCR5380_pread(struct Scsi_Host *instance, unsigned char *dst, int len)
+static inline int t128_pread(struct Scsi_Host *instance,
+                             unsigned char *dst, int len)
 {
 	struct NCR5380_hostdata *hostdata = shost_priv(instance);
 	void __iomem *reg, *base = hostdata->base;
@@ -338,7 +338,7 @@ NCR5380_pread(struct Scsi_Host *instance
 }
 
 /*
- * Function : int NCR5380_pwrite (struct Scsi_Host *instance, 
+ * Function : int t128_pwrite (struct Scsi_Host *instance,
  *	unsigned char *src, int len)
  *
  * Purpose : Fast 5380 pseudo-dma write function, transfers len bytes from
@@ -350,8 +350,8 @@ NCR5380_pread(struct Scsi_Host *instance
  * 	timeout.
  */
 
-static inline int
-NCR5380_pwrite(struct Scsi_Host *instance, unsigned char *src, int len)
+static inline int t128_pwrite(struct Scsi_Host *instance,
+                              unsigned char *src, int len)
 {
 	struct NCR5380_hostdata *hostdata = shost_priv(instance);
 	void __iomem *reg, *base = hostdata->base;
Index: linux/drivers/scsi/t128.h
===================================================================
--- linux.orig/drivers/scsi/t128.h	2016-03-23 21:09:34.000000000 +1100
+++ linux/drivers/scsi/t128.h	2016-03-23 21:09:37.000000000 +1100
@@ -77,6 +77,8 @@
 #define NCR5380_write(reg, value) writeb((value),(T128_address(reg)))
 
 #define NCR5380_dma_xfer_len(instance, cmd, phase)	(cmd->transfersize)
+#define NCR5380_dma_recv_setup		t128_pread
+#define NCR5380_dma_send_setup		t128_pwrite
 
 #define NCR5380_intr t128_intr
 #define NCR5380_queue_command t128_queue_command
Index: linux/drivers/scsi/dmx3191d.c
===================================================================
--- linux.orig/drivers/scsi/dmx3191d.c	2016-03-23 21:09:28.000000000 +1100
+++ linux/drivers/scsi/dmx3191d.c	2016-03-23 21:09:37.000000000 +1100
@@ -40,8 +40,8 @@
 #define NCR5380_write(reg, value)	outb(value, instance->io_port + reg)
 
 #define NCR5380_dma_xfer_len(instance, cmd, phase)	(0)
-#define NCR5380_pread(instance, dst, len)		(0)
-#define NCR5380_pwrite(instance, src, len)		(0)
+#define NCR5380_dma_recv_setup(instance, dst, len)	(0)
+#define NCR5380_dma_send_setup(instance, src, len)	(0)
 
 #define NCR5380_implementation_fields	/* none */

^ permalink raw reply	[flat|nested] 60+ messages in thread

* [PATCH v4 08/23] ncr5380: Use DMA hooks for PDMA
@ 2016-03-23 10:10   ` Finn Thain
  0 siblings, 0 replies; 60+ messages in thread
From: Finn Thain @ 2016-03-23 10:10 UTC (permalink / raw)
  To: linux-arm-kernel

An embedded and charset-unspecified text was scrubbed...
Name: ncr5380-rename-pread-and-pwrite
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20160323/c302b8ff/attachment.ksh>

^ permalink raw reply	[flat|nested] 60+ messages in thread

* [PATCH v4 09/23] ncr5380: Adopt uniform DMA setup convention
  2016-03-23 10:10 ` Finn Thain
  (?)
@ 2016-03-23 10:10   ` Finn Thain
  -1 siblings, 0 replies; 60+ messages in thread
From: Finn Thain @ 2016-03-23 10:10 UTC (permalink / raw)
  To: James E.J. Bottomley, Martin K. Petersen, Michael Schmitz,
	linux-m68k, linux-scsi, linux-kernel, Russell King,
	linux-arm-kernel
  Cc: Ondrej Zary, Sam Creasey

[-- Attachment #1: ncr5380-dma-setup-api --]
[-- Type: text/plain, Size: 6044 bytes --]

Standardize the DMA setup hooks so that the DMA implementation in
atari_NCR5380.c can be reconciled with pseudo DMA implementation in
NCR5380.c.

Calls to NCR5380_dma_recv_setup() and NCR5380_dma_send_setup() return
a negative value on failure, zero on PDMA transfer success and a positive
byte count for DMA setup success.

This convention is not entirely new, but is now applied consistently.

Also remove a pointless Status Register access: the *phase assignment is
redundant because after NCR5380_transfer_dma() returns control to
NCR5380_information_transfer(), that routine then returns control
to NCR5380_main(), which means *phase is dead.

Signed-off-by: Finn Thain <fthain@telegraphics.com.au>
Reviewed-by: Hannes Reinecke <hare@suse.com>
Tested-by: Michael Schmitz <schmitzmic@gmail.com>
Tested-by: Ondrej Zary <linux@rainbow-software.org>

---
 drivers/scsi/NCR5380.c      |   21 ++++++++++-----------
 drivers/scsi/arm/cumana_1.c |   10 ++++++++--
 drivers/scsi/arm/oak.c      |    4 ++--
 drivers/scsi/atari_scsi.c   |    3 ---
 4 files changed, 20 insertions(+), 18 deletions(-)

Index: linux/drivers/scsi/NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/NCR5380.c	2016-03-23 21:09:37.000000000 +1100
+++ linux/drivers/scsi/NCR5380.c	2016-03-23 21:09:44.000000000 +1100
@@ -1431,7 +1431,7 @@ static int NCR5380_transfer_dma(struct S
 	register unsigned char p = *phase;
 	register unsigned char *d = *data;
 	unsigned char tmp;
-	int foo;
+	int result;
 
 	if ((tmp = (NCR5380_read(STATUS_REG) & PHASE_MASK)) != p) {
 		*phase = tmp;
@@ -1505,9 +1505,9 @@ static int NCR5380_transfer_dma(struct S
  */
 
 	if (p & SR_IO) {
-		foo = NCR5380_dma_recv_setup(instance, d,
+		result = NCR5380_dma_recv_setup(instance, d,
 			hostdata->flags & FLAG_DMA_FIXUP ? c - 1 : c);
-		if (!foo && (hostdata->flags & FLAG_DMA_FIXUP)) {
+		if (!result && (hostdata->flags & FLAG_DMA_FIXUP)) {
 			/*
 			 * The workaround was to transfer fewer bytes than we
 			 * intended to with the pseudo-DMA read function, wait for
@@ -1525,19 +1525,19 @@ static int NCR5380_transfer_dma(struct S
 
 			if (NCR5380_poll_politely(instance, BUS_AND_STATUS_REG,
 			                          BASR_DRQ, BASR_DRQ, HZ) < 0) {
-				foo = -1;
+				result = -1;
 				shost_printk(KERN_ERR, instance, "PDMA read: DRQ timeout\n");
 			}
 			if (NCR5380_poll_politely(instance, STATUS_REG,
 			                          SR_REQ, 0, HZ) < 0) {
-				foo = -1;
+				result = -1;
 				shost_printk(KERN_ERR, instance, "PDMA read: !REQ timeout\n");
 			}
 			d[c - 1] = NCR5380_read(INPUT_DATA_REG);
 		}
 	} else {
-		foo = NCR5380_dma_send_setup(instance, d, c);
-		if (!foo && (hostdata->flags & FLAG_DMA_FIXUP)) {
+		result = NCR5380_dma_send_setup(instance, d, c);
+		if (!result && (hostdata->flags & FLAG_DMA_FIXUP)) {
 			/*
 			 * Wait for the last byte to be sent.  If REQ is being asserted for
 			 * the byte we're interested, we'll ACK it and it will go false.
@@ -1545,7 +1545,7 @@ static int NCR5380_transfer_dma(struct S
 			if (NCR5380_poll_politely2(instance,
 			     BUS_AND_STATUS_REG, BASR_DRQ, BASR_DRQ,
 			     BUS_AND_STATUS_REG, BASR_PHASE_MATCH, 0, HZ) < 0) {
-				foo = -1;
+				result = -1;
 				shost_printk(KERN_ERR, instance, "PDMA write: DRQ and phase timeout\n");
 			}
 		}
@@ -1555,8 +1555,7 @@ static int NCR5380_transfer_dma(struct S
 	NCR5380_read(RESET_PARITY_INTERRUPT_REG);
 	*data = d + c;
 	*count = 0;
-	*phase = NCR5380_read(STATUS_REG) & PHASE_MASK;
-	return foo;
+	return result;
 }
 
 /*
@@ -1652,7 +1651,7 @@ static void NCR5380_information_transfer
 				if (!cmd->device->borken)
 					transfersize = NCR5380_dma_xfer_len(instance, cmd, phase);
 
-				if (transfersize) {
+				if (transfersize > 0) {
 					len = transfersize;
 					if (NCR5380_transfer_dma(instance, &phase,
 					    &len, (unsigned char **)&cmd->SCp.ptr)) {
Index: linux/drivers/scsi/arm/cumana_1.c
===================================================================
--- linux.orig/drivers/scsi/arm/cumana_1.c	2016-03-23 21:09:37.000000000 +1100
+++ linux/drivers/scsi/arm/cumana_1.c	2016-03-23 21:09:44.000000000 +1100
@@ -101,7 +101,10 @@ static inline int cumanascsi_pwrite(stru
   }
 end:
   writeb(priv(host)->ctrl | 0x40, priv(host)->base + CTRL);
-  return len;
+
+	if (len)
+		return -1;
+	return 0;
 }
 
 static inline int cumanascsi_pread(struct Scsi_Host *host,
@@ -163,7 +166,10 @@ static inline int cumanascsi_pread(struc
   }
 end:
   writeb(priv(host)->ctrl | 0x40, priv(host)->base + CTRL);
-  return len;
+
+	if (len)
+		return -1;
+	return 0;
 }
 
 static unsigned char cumanascsi_read(struct Scsi_Host *host, unsigned int reg)
Index: linux/drivers/scsi/arm/oak.c
===================================================================
--- linux.orig/drivers/scsi/arm/oak.c	2016-03-23 21:09:37.000000000 +1100
+++ linux/drivers/scsi/arm/oak.c	2016-03-23 21:09:44.000000000 +1100
@@ -47,13 +47,13 @@ static inline int oakscsi_pwrite(struct
   void __iomem *base = priv(instance)->base;
 
 printk("writing %p len %d\n",addr, len);
-  if(!len) return -1;
 
   while(1)
   {
     int status;
     while (((status = readw(base + STAT)) & 0x100)==0);
   }
+  return 0;
 }
 
 static inline int oakscsi_pread(struct Scsi_Host *instance,
@@ -74,7 +74,7 @@ printk("reading %p len %d\n", addr, len)
       if(status & 0x200 || !timeout)
       {
         printk("status = %08X\n", status);
-        return 1;
+        return -1;
       }
     }
 
Index: linux/drivers/scsi/atari_scsi.c
===================================================================
--- linux.orig/drivers/scsi/atari_scsi.c	2016-03-23 21:09:24.000000000 +1100
+++ linux/drivers/scsi/atari_scsi.c	2016-03-23 21:09:44.000000000 +1100
@@ -527,9 +527,6 @@ static unsigned long atari_scsi_dma_setu
 	 */
 	dma_cache_maintenance(addr, count, dir);
 
-	if (count == 0)
-		printk(KERN_NOTICE "SCSI warning: DMA programmed for 0 bytes !\n");
-
 	if (IS_A_TT()) {
 		tt_scsi_dma.dma_ctrl = dir;
 		SCSI_DMA_WRITE_P(dma_addr, addr);

^ permalink raw reply	[flat|nested] 60+ messages in thread

* [PATCH v4 09/23] ncr5380: Adopt uniform DMA setup convention
@ 2016-03-23 10:10   ` Finn Thain
  0 siblings, 0 replies; 60+ messages in thread
From: Finn Thain @ 2016-03-23 10:10 UTC (permalink / raw)
  To: James E.J. Bottomley, Martin K. Petersen, Michael Schmitz,
	linux-m68k, linux-scsi, linux-kernel, Russell King,
	linux-arm-kernel
  Cc: Sam Creasey, Ondrej Zary

[-- Attachment #1: ncr5380-dma-setup-api --]
[-- Type: text/plain, Size: 6044 bytes --]

Standardize the DMA setup hooks so that the DMA implementation in
atari_NCR5380.c can be reconciled with pseudo DMA implementation in
NCR5380.c.

Calls to NCR5380_dma_recv_setup() and NCR5380_dma_send_setup() return
a negative value on failure, zero on PDMA transfer success and a positive
byte count for DMA setup success.

This convention is not entirely new, but is now applied consistently.

Also remove a pointless Status Register access: the *phase assignment is
redundant because after NCR5380_transfer_dma() returns control to
NCR5380_information_transfer(), that routine then returns control
to NCR5380_main(), which means *phase is dead.

Signed-off-by: Finn Thain <fthain@telegraphics.com.au>
Reviewed-by: Hannes Reinecke <hare@suse.com>
Tested-by: Michael Schmitz <schmitzmic@gmail.com>
Tested-by: Ondrej Zary <linux@rainbow-software.org>

---
 drivers/scsi/NCR5380.c      |   21 ++++++++++-----------
 drivers/scsi/arm/cumana_1.c |   10 ++++++++--
 drivers/scsi/arm/oak.c      |    4 ++--
 drivers/scsi/atari_scsi.c   |    3 ---
 4 files changed, 20 insertions(+), 18 deletions(-)

Index: linux/drivers/scsi/NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/NCR5380.c	2016-03-23 21:09:37.000000000 +1100
+++ linux/drivers/scsi/NCR5380.c	2016-03-23 21:09:44.000000000 +1100
@@ -1431,7 +1431,7 @@ static int NCR5380_transfer_dma(struct S
 	register unsigned char p = *phase;
 	register unsigned char *d = *data;
 	unsigned char tmp;
-	int foo;
+	int result;
 
 	if ((tmp = (NCR5380_read(STATUS_REG) & PHASE_MASK)) != p) {
 		*phase = tmp;
@@ -1505,9 +1505,9 @@ static int NCR5380_transfer_dma(struct S
  */
 
 	if (p & SR_IO) {
-		foo = NCR5380_dma_recv_setup(instance, d,
+		result = NCR5380_dma_recv_setup(instance, d,
 			hostdata->flags & FLAG_DMA_FIXUP ? c - 1 : c);
-		if (!foo && (hostdata->flags & FLAG_DMA_FIXUP)) {
+		if (!result && (hostdata->flags & FLAG_DMA_FIXUP)) {
 			/*
 			 * The workaround was to transfer fewer bytes than we
 			 * intended to with the pseudo-DMA read function, wait for
@@ -1525,19 +1525,19 @@ static int NCR5380_transfer_dma(struct S
 
 			if (NCR5380_poll_politely(instance, BUS_AND_STATUS_REG,
 			                          BASR_DRQ, BASR_DRQ, HZ) < 0) {
-				foo = -1;
+				result = -1;
 				shost_printk(KERN_ERR, instance, "PDMA read: DRQ timeout\n");
 			}
 			if (NCR5380_poll_politely(instance, STATUS_REG,
 			                          SR_REQ, 0, HZ) < 0) {
-				foo = -1;
+				result = -1;
 				shost_printk(KERN_ERR, instance, "PDMA read: !REQ timeout\n");
 			}
 			d[c - 1] = NCR5380_read(INPUT_DATA_REG);
 		}
 	} else {
-		foo = NCR5380_dma_send_setup(instance, d, c);
-		if (!foo && (hostdata->flags & FLAG_DMA_FIXUP)) {
+		result = NCR5380_dma_send_setup(instance, d, c);
+		if (!result && (hostdata->flags & FLAG_DMA_FIXUP)) {
 			/*
 			 * Wait for the last byte to be sent.  If REQ is being asserted for
 			 * the byte we're interested, we'll ACK it and it will go false.
@@ -1545,7 +1545,7 @@ static int NCR5380_transfer_dma(struct S
 			if (NCR5380_poll_politely2(instance,
 			     BUS_AND_STATUS_REG, BASR_DRQ, BASR_DRQ,
 			     BUS_AND_STATUS_REG, BASR_PHASE_MATCH, 0, HZ) < 0) {
-				foo = -1;
+				result = -1;
 				shost_printk(KERN_ERR, instance, "PDMA write: DRQ and phase timeout\n");
 			}
 		}
@@ -1555,8 +1555,7 @@ static int NCR5380_transfer_dma(struct S
 	NCR5380_read(RESET_PARITY_INTERRUPT_REG);
 	*data = d + c;
 	*count = 0;
-	*phase = NCR5380_read(STATUS_REG) & PHASE_MASK;
-	return foo;
+	return result;
 }
 
 /*
@@ -1652,7 +1651,7 @@ static void NCR5380_information_transfer
 				if (!cmd->device->borken)
 					transfersize = NCR5380_dma_xfer_len(instance, cmd, phase);
 
-				if (transfersize) {
+				if (transfersize > 0) {
 					len = transfersize;
 					if (NCR5380_transfer_dma(instance, &phase,
 					    &len, (unsigned char **)&cmd->SCp.ptr)) {
Index: linux/drivers/scsi/arm/cumana_1.c
===================================================================
--- linux.orig/drivers/scsi/arm/cumana_1.c	2016-03-23 21:09:37.000000000 +1100
+++ linux/drivers/scsi/arm/cumana_1.c	2016-03-23 21:09:44.000000000 +1100
@@ -101,7 +101,10 @@ static inline int cumanascsi_pwrite(stru
   }
 end:
   writeb(priv(host)->ctrl | 0x40, priv(host)->base + CTRL);
-  return len;
+
+	if (len)
+		return -1;
+	return 0;
 }
 
 static inline int cumanascsi_pread(struct Scsi_Host *host,
@@ -163,7 +166,10 @@ static inline int cumanascsi_pread(struc
   }
 end:
   writeb(priv(host)->ctrl | 0x40, priv(host)->base + CTRL);
-  return len;
+
+	if (len)
+		return -1;
+	return 0;
 }
 
 static unsigned char cumanascsi_read(struct Scsi_Host *host, unsigned int reg)
Index: linux/drivers/scsi/arm/oak.c
===================================================================
--- linux.orig/drivers/scsi/arm/oak.c	2016-03-23 21:09:37.000000000 +1100
+++ linux/drivers/scsi/arm/oak.c	2016-03-23 21:09:44.000000000 +1100
@@ -47,13 +47,13 @@ static inline int oakscsi_pwrite(struct
   void __iomem *base = priv(instance)->base;
 
 printk("writing %p len %d\n",addr, len);
-  if(!len) return -1;
 
   while(1)
   {
     int status;
     while (((status = readw(base + STAT)) & 0x100)==0);
   }
+  return 0;
 }
 
 static inline int oakscsi_pread(struct Scsi_Host *instance,
@@ -74,7 +74,7 @@ printk("reading %p len %d\n", addr, len)
       if(status & 0x200 || !timeout)
       {
         printk("status = %08X\n", status);
-        return 1;
+        return -1;
       }
     }
 
Index: linux/drivers/scsi/atari_scsi.c
===================================================================
--- linux.orig/drivers/scsi/atari_scsi.c	2016-03-23 21:09:24.000000000 +1100
+++ linux/drivers/scsi/atari_scsi.c	2016-03-23 21:09:44.000000000 +1100
@@ -527,9 +527,6 @@ static unsigned long atari_scsi_dma_setu
 	 */
 	dma_cache_maintenance(addr, count, dir);
 
-	if (count == 0)
-		printk(KERN_NOTICE "SCSI warning: DMA programmed for 0 bytes !\n");
-
 	if (IS_A_TT()) {
 		tt_scsi_dma.dma_ctrl = dir;
 		SCSI_DMA_WRITE_P(dma_addr, addr);

^ permalink raw reply	[flat|nested] 60+ messages in thread

* [PATCH v4 09/23] ncr5380: Adopt uniform DMA setup convention
@ 2016-03-23 10:10   ` Finn Thain
  0 siblings, 0 replies; 60+ messages in thread
From: Finn Thain @ 2016-03-23 10:10 UTC (permalink / raw)
  To: linux-arm-kernel

An embedded and charset-unspecified text was scrubbed...
Name: ncr5380-dma-setup-api
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20160323/0448a288/attachment.ksh>

^ permalink raw reply	[flat|nested] 60+ messages in thread

* [PATCH v4 10/23] ncr5380: Merge DMA implementation from atari_NCR5380 core driver
  2016-03-23 10:10 ` Finn Thain
  (?)
@ 2016-03-23 10:10   ` Finn Thain
  -1 siblings, 0 replies; 60+ messages in thread
From: Finn Thain @ 2016-03-23 10:10 UTC (permalink / raw)
  To: James E.J. Bottomley, Martin K. Petersen, Michael Schmitz,
	linux-m68k, linux-scsi, linux-kernel, Russell King,
	linux-arm-kernel
  Cc: Ondrej Zary, Sam Creasey

[-- Attachment #1: ncr5380-merge-atari-dma-algorithm --]
[-- Type: text/plain, Size: 16359 bytes --]

Adopt the DMA implementation from atari_NCR5380.c. This means that
atari_scsi and sun3_scsi can make use of the NCR5380.c core driver
and the atari_NCR5380.c driver fork can be made redundant.

Signed-off-by: Finn Thain <fthain@telegraphics.com.au>
Reviewed-by: Hannes Reinecke <hare@suse.com>
Tested-by: Michael Schmitz <schmitzmic@gmail.com>
Tested-by: Ondrej Zary <linux@rainbow-software.org>

---
 drivers/scsi/NCR5380.c      |  170 +++++++++++++++++++++++++++++++++++---------
 drivers/scsi/arm/cumana_1.c |    3 
 drivers/scsi/arm/oak.c      |    3 
 drivers/scsi/dmx3191d.c     |    1 
 drivers/scsi/dtc.c          |    2 
 drivers/scsi/dtc.h          |    1 
 drivers/scsi/g_NCR5380.c    |    2 
 drivers/scsi/g_NCR5380.h    |    1 
 drivers/scsi/mac_scsi.c     |    3 
 drivers/scsi/pas16.c        |    2 
 drivers/scsi/pas16.h        |    1 
 drivers/scsi/t128.c         |    2 
 drivers/scsi/t128.h         |    1 
 13 files changed, 152 insertions(+), 40 deletions(-)

Index: linux/drivers/scsi/NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/NCR5380.c	2016-03-23 21:09:44.000000000 +1100
+++ linux/drivers/scsi/NCR5380.c	2016-03-23 21:09:47.000000000 +1100
@@ -31,9 +31,6 @@
 
 /*
  * Further development / testing that should be done :
- * 1.  Cleanup the NCR5380_transfer_dma function and DMA operation complete
- * code so that everything does the same thing that's done at the
- * end of a pseudo-DMA read operation.
  *
  * 4.  Test SCSI-II tagged queueing (I have no devices which support
  * tagged queueing)
@@ -117,6 +114,8 @@
  *
  * PSEUDO_DMA - if defined, PSEUDO DMA is used during the data transfer phases.
  *
+ * REAL_DMA - if defined, REAL DMA is used during the data transfer phases.
+ *
  * These macros MUST be defined :
  *
  * NCR5380_read(register)  - read from the specified register
@@ -801,6 +800,72 @@ static void NCR5380_main(struct work_str
 	} while (!done);
 }
 
+/*
+ * NCR5380_dma_complete - finish DMA transfer
+ * @instance: the scsi host instance
+ *
+ * Called by the interrupt handler when DMA finishes or a phase
+ * mismatch occurs (which would end the DMA transfer).
+ */
+
+static void NCR5380_dma_complete(struct Scsi_Host *instance)
+{
+	struct NCR5380_hostdata *hostdata = shost_priv(instance);
+	int transferred;
+	unsigned char **data;
+	int *count;
+	int saved_data = 0, overrun = 0;
+	unsigned char p;
+
+	if (hostdata->read_overruns) {
+		p = hostdata->connected->SCp.phase;
+		if (p & SR_IO) {
+			udelay(10);
+			if ((NCR5380_read(BUS_AND_STATUS_REG) &
+			     (BASR_PHASE_MATCH | BASR_ACK)) ==
+			    (BASR_PHASE_MATCH | BASR_ACK)) {
+				saved_data = NCR5380_read(INPUT_DATA_REG);
+				overrun = 1;
+				dsprintk(NDEBUG_DMA, instance, "read overrun handled\n");
+			}
+		}
+	}
+
+	NCR5380_write(MODE_REG, MR_BASE);
+	NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
+	NCR5380_read(RESET_PARITY_INTERRUPT_REG);
+
+	transferred = hostdata->dma_len - NCR5380_dma_residual(instance);
+	hostdata->dma_len = 0;
+
+	data = (unsigned char **)&hostdata->connected->SCp.ptr;
+	count = &hostdata->connected->SCp.this_residual;
+	*data += transferred;
+	*count -= transferred;
+
+	if (hostdata->read_overruns) {
+		int cnt, toPIO;
+
+		if ((NCR5380_read(STATUS_REG) & PHASE_MASK) == p && (p & SR_IO)) {
+			cnt = toPIO = hostdata->read_overruns;
+			if (overrun) {
+				dsprintk(NDEBUG_DMA, instance,
+				         "Got an input overrun, using saved byte\n");
+				*(*data)++ = saved_data;
+				(*count)--;
+				cnt--;
+				toPIO--;
+			}
+			if (toPIO > 0) {
+				dsprintk(NDEBUG_DMA, instance,
+				         "Doing %d byte PIO to 0x%p\n", cnt, *data);
+				NCR5380_transfer_pio(instance, &p, &cnt, data);
+				*count -= toPIO - cnt;
+			}
+		}
+	}
+}
+
 #ifndef DONT_USE_INTR
 
 /**
@@ -855,7 +920,22 @@ static irqreturn_t NCR5380_intr(int irq,
 		dsprintk(NDEBUG_INTR, instance, "IRQ %d, BASR 0x%02x, SR 0x%02x, MR 0x%02x\n",
 		         irq, basr, sr, mr);
 
-		if ((NCR5380_read(CURRENT_SCSI_DATA_REG) & hostdata->id_mask) &&
+		if ((mr & MR_DMA_MODE) || (mr & MR_MONITOR_BSY)) {
+			/* Probably End of DMA, Phase Mismatch or Loss of BSY.
+			 * We ack IRQ after clearing Mode Register. Workarounds
+			 * for End of DMA errata need to happen in DMA Mode.
+			 */
+
+			dsprintk(NDEBUG_INTR, instance, "interrupt in DMA mode\n");
+
+			if (hostdata->connected) {
+				NCR5380_dma_complete(instance);
+				queue_work(hostdata->work_q, &hostdata->main_task);
+			} else {
+				NCR5380_write(MODE_REG, MR_BASE);
+				NCR5380_read(RESET_PARITY_INTERRUPT_REG);
+			}
+		} else if ((NCR5380_read(CURRENT_SCSI_DATA_REG) & hostdata->id_mask) &&
 		    (sr & (SR_SEL | SR_IO | SR_BSY | SR_RST)) == (SR_SEL | SR_IO)) {
 			/* Probably reselected */
 			NCR5380_write(SELECT_ENABLE_REG, 0);
@@ -1431,28 +1511,38 @@ static int NCR5380_transfer_dma(struct S
 	register unsigned char p = *phase;
 	register unsigned char *d = *data;
 	unsigned char tmp;
-	int result;
+	int result = 0;
 
 	if ((tmp = (NCR5380_read(STATUS_REG) & PHASE_MASK)) != p) {
 		*phase = tmp;
 		return -1;
 	}
 
-	NCR5380_write(TARGET_COMMAND_REG, PHASE_SR_TO_TCR(p));
+	hostdata->connected->SCp.phase = p;
 
-	/*
-	 * Note : on my sample board, watch-dog timeouts occurred when interrupts
-	 * were not disabled for the duration of a single DMA transfer, from
-	 * before the setting of DMA mode to after transfer of the last byte.
-	 */
+	if (p & SR_IO) {
+		if (hostdata->read_overruns)
+			c -= hostdata->read_overruns;
+		else if (hostdata->flags & FLAG_DMA_FIXUP)
+			--c;
+	}
 
-	if (hostdata->flags & FLAG_DMA_FIXUP)
-		NCR5380_write(MODE_REG, MR_BASE | MR_DMA_MODE | MR_MONITOR_BSY);
-	else
-		NCR5380_write(MODE_REG, MR_BASE | MR_DMA_MODE | MR_MONITOR_BSY |
-		                        MR_ENABLE_EOP_INTR);
+	dsprintk(NDEBUG_DMA, instance, "initializing DMA %s: length %d, address %p\n",
+	         (p & SR_IO) ? "receive" : "send", c, d);
 
-	dprintk(NDEBUG_DMA, "scsi%d : mode reg = 0x%X\n", instance->host_no, NCR5380_read(MODE_REG));
+	NCR5380_write(TARGET_COMMAND_REG, PHASE_SR_TO_TCR(p));
+	NCR5380_write(MODE_REG, MR_BASE | MR_DMA_MODE | MR_MONITOR_BSY |
+	                        MR_ENABLE_EOP_INTR);
+
+	if (!(hostdata->flags & FLAG_LATE_DMA_SETUP)) {
+		/* On the Medusa, it is a must to initialize the DMA before
+		 * starting the NCR. This is also the cleaner way for the TT.
+		 */
+		if (p & SR_IO)
+			result = NCR5380_dma_recv_setup(instance, d, c);
+		else
+			result = NCR5380_dma_send_setup(instance, d, c);
+	}
 
 	/*
 	 * On the PAS16 at least I/O recovery delays are not needed here.
@@ -1470,6 +1560,29 @@ static int NCR5380_transfer_dma(struct S
 		NCR5380_io_delay(1);
 	}
 
+	if (hostdata->flags & FLAG_LATE_DMA_SETUP) {
+		/* On the Falcon, the DMA setup must be done after the last
+		 * NCR access, else the DMA setup gets trashed!
+		 */
+		if (p & SR_IO)
+			result = NCR5380_dma_recv_setup(instance, d, c);
+		else
+			result = NCR5380_dma_send_setup(instance, d, c);
+	}
+
+	/* On failure, NCR5380_dma_xxxx_setup() returns a negative int. */
+	if (result < 0)
+		return result;
+
+	/* For real DMA, result is the byte count. DMA interrupt is expected. */
+	if (result > 0) {
+		hostdata->dma_len = result;
+		return 0;
+	}
+
+	/* The result is zero iff pseudo DMA send/receive was completed. */
+	hostdata->dma_len = c;
+
 /*
  * A note regarding the DMA errata workarounds for early NMOS silicon.
  *
@@ -1504,10 +1617,8 @@ static int NCR5380_transfer_dma(struct S
  * request.
  */
 
-	if (p & SR_IO) {
-		result = NCR5380_dma_recv_setup(instance, d,
-			hostdata->flags & FLAG_DMA_FIXUP ? c - 1 : c);
-		if (!result && (hostdata->flags & FLAG_DMA_FIXUP)) {
+	if (hostdata->flags & FLAG_DMA_FIXUP) {
+		if (p & SR_IO) {
 			/*
 			 * The workaround was to transfer fewer bytes than we
 			 * intended to with the pseudo-DMA read function, wait for
@@ -1533,11 +1644,8 @@ static int NCR5380_transfer_dma(struct S
 				result = -1;
 				shost_printk(KERN_ERR, instance, "PDMA read: !REQ timeout\n");
 			}
-			d[c - 1] = NCR5380_read(INPUT_DATA_REG);
-		}
-	} else {
-		result = NCR5380_dma_send_setup(instance, d, c);
-		if (!result && (hostdata->flags & FLAG_DMA_FIXUP)) {
+			d[*count - 1] = NCR5380_read(INPUT_DATA_REG);
+		} else {
 			/*
 			 * Wait for the last byte to be sent.  If REQ is being asserted for
 			 * the byte we're interested, we'll ACK it and it will go false.
@@ -1550,11 +1658,8 @@ static int NCR5380_transfer_dma(struct S
 			}
 		}
 	}
-	NCR5380_write(MODE_REG, MR_BASE);
-	NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
-	NCR5380_read(RESET_PARITY_INTERRUPT_REG);
-	*data = d + c;
-	*count = 0;
+
+	NCR5380_dma_complete(instance);
 	return result;
 }
 
@@ -1667,8 +1772,7 @@ static void NCR5380_information_transfer
 						do_abort(instance);
 						cmd->result = DID_ERROR << 16;
 						/* XXX - need to source or sink data here, as appropriate */
-					} else
-						cmd->SCp.this_residual -= transfersize - len;
+					}
 				} else {
 					/* Break up transfer into 3 ms chunks,
 					 * presuming 6 accesses per handshake.
Index: linux/drivers/scsi/arm/cumana_1.c
===================================================================
--- linux.orig/drivers/scsi/arm/cumana_1.c	2016-03-23 21:09:44.000000000 +1100
+++ linux/drivers/scsi/arm/cumana_1.c	2016-03-23 21:09:47.000000000 +1100
@@ -20,6 +20,7 @@
 #define NCR5380_dma_xfer_len(instance, cmd, phase)	(cmd->transfersize)
 #define NCR5380_dma_recv_setup		cumanascsi_pread
 #define NCR5380_dma_send_setup		cumanascsi_pwrite
+#define NCR5380_dma_residual(instance)	(0)
 
 #define NCR5380_intr			cumanascsi_intr
 #define NCR5380_queue_command		cumanascsi_queue_command
@@ -245,7 +246,7 @@ static int cumanascsi1_probe(struct expa
 
 	host->irq = ec->irq;
 
-	ret = NCR5380_init(host, FLAG_DMA_FIXUP);
+	ret = NCR5380_init(host, FLAG_DMA_FIXUP | FLAG_LATE_DMA_SETUP);
 	if (ret)
 		goto out_unmap;
 
Index: linux/drivers/scsi/arm/oak.c
===================================================================
--- linux.orig/drivers/scsi/arm/oak.c	2016-03-23 21:09:44.000000000 +1100
+++ linux/drivers/scsi/arm/oak.c	2016-03-23 21:09:47.000000000 +1100
@@ -26,6 +26,7 @@
 #define NCR5380_dma_xfer_len(instance, cmd, phase)	(0)
 #define NCR5380_dma_recv_setup		oakscsi_pread
 #define NCR5380_dma_send_setup		oakscsi_pwrite
+#define NCR5380_dma_residual(instance)	(0)
 
 #define NCR5380_queue_command		oakscsi_queue_command
 #define NCR5380_info			oakscsi_info
@@ -144,7 +145,7 @@ static int oakscsi_probe(struct expansio
 	host->irq = NO_IRQ;
 	host->n_io_port = 255;
 
-	ret = NCR5380_init(host, FLAG_DMA_FIXUP);
+	ret = NCR5380_init(host, FLAG_DMA_FIXUP | FLAG_LATE_DMA_SETUP);
 	if (ret)
 		goto out_unmap;
 
Index: linux/drivers/scsi/dmx3191d.c
===================================================================
--- linux.orig/drivers/scsi/dmx3191d.c	2016-03-23 21:09:37.000000000 +1100
+++ linux/drivers/scsi/dmx3191d.c	2016-03-23 21:09:47.000000000 +1100
@@ -42,6 +42,7 @@
 #define NCR5380_dma_xfer_len(instance, cmd, phase)	(0)
 #define NCR5380_dma_recv_setup(instance, dst, len)	(0)
 #define NCR5380_dma_send_setup(instance, src, len)	(0)
+#define NCR5380_dma_residual(instance)			(0)
 
 #define NCR5380_implementation_fields	/* none */
 
Index: linux/drivers/scsi/dtc.h
===================================================================
--- linux.orig/drivers/scsi/dtc.h	2016-03-23 21:09:37.000000000 +1100
+++ linux/drivers/scsi/dtc.h	2016-03-23 21:09:47.000000000 +1100
@@ -23,6 +23,7 @@
         dtc_dma_xfer_len(cmd)
 #define NCR5380_dma_recv_setup		dtc_pread
 #define NCR5380_dma_send_setup		dtc_pwrite
+#define NCR5380_dma_residual(instance)	(0)
 
 #define NCR5380_intr			dtc_intr
 #define NCR5380_queue_command		dtc_queue_command
Index: linux/drivers/scsi/g_NCR5380.h
===================================================================
--- linux.orig/drivers/scsi/g_NCR5380.h	2016-03-23 21:09:37.000000000 +1100
+++ linux/drivers/scsi/g_NCR5380.h	2016-03-23 21:09:47.000000000 +1100
@@ -64,6 +64,7 @@
         generic_NCR5380_dma_xfer_len(instance, cmd)
 #define NCR5380_dma_recv_setup		generic_NCR5380_pread
 #define NCR5380_dma_send_setup		generic_NCR5380_pwrite
+#define NCR5380_dma_residual(instance)	(0)
 
 #define NCR5380_intr generic_NCR5380_intr
 #define NCR5380_queue_command generic_NCR5380_queue_command
Index: linux/drivers/scsi/mac_scsi.c
===================================================================
--- linux.orig/drivers/scsi/mac_scsi.c	2016-03-23 21:09:37.000000000 +1100
+++ linux/drivers/scsi/mac_scsi.c	2016-03-23 21:09:47.000000000 +1100
@@ -37,6 +37,7 @@
         macscsi_dma_xfer_len(instance, cmd)
 #define NCR5380_dma_recv_setup          macscsi_pread
 #define NCR5380_dma_send_setup          macscsi_pwrite
+#define NCR5380_dma_residual(instance)  (0)
 
 #define NCR5380_intr                    macscsi_intr
 #define NCR5380_queue_command           macscsi_queue_command
@@ -386,7 +387,7 @@ static int __init mac_scsi_probe(struct
 #endif
 	host_flags |= setup_toshiba_delay > 0 ? FLAG_TOSHIBA_DELAY : 0;
 
-	error = NCR5380_init(instance, host_flags);
+	error = NCR5380_init(instance, host_flags | FLAG_LATE_DMA_SETUP);
 	if (error)
 		goto fail_init;
 
Index: linux/drivers/scsi/pas16.h
===================================================================
--- linux.orig/drivers/scsi/pas16.h	2016-03-23 21:09:37.000000000 +1100
+++ linux/drivers/scsi/pas16.h	2016-03-23 21:09:47.000000000 +1100
@@ -105,6 +105,7 @@
 #define NCR5380_dma_xfer_len(instance, cmd, phase)	(cmd->transfersize)
 #define NCR5380_dma_recv_setup		pas16_pread
 #define NCR5380_dma_send_setup		pas16_pwrite
+#define NCR5380_dma_residual(instance)	(0)
 
 #define NCR5380_intr pas16_intr
 #define NCR5380_queue_command pas16_queue_command
Index: linux/drivers/scsi/t128.h
===================================================================
--- linux.orig/drivers/scsi/t128.h	2016-03-23 21:09:37.000000000 +1100
+++ linux/drivers/scsi/t128.h	2016-03-23 21:09:47.000000000 +1100
@@ -79,6 +79,7 @@
 #define NCR5380_dma_xfer_len(instance, cmd, phase)	(cmd->transfersize)
 #define NCR5380_dma_recv_setup		t128_pread
 #define NCR5380_dma_send_setup		t128_pwrite
+#define NCR5380_dma_residual(instance)	(0)
 
 #define NCR5380_intr t128_intr
 #define NCR5380_queue_command t128_queue_command
Index: linux/drivers/scsi/dtc.c
===================================================================
--- linux.orig/drivers/scsi/dtc.c	2016-03-23 21:09:37.000000000 +1100
+++ linux/drivers/scsi/dtc.c	2016-03-23 21:09:47.000000000 +1100
@@ -228,7 +228,7 @@ found:
 		instance->base = addr;
 		((struct NCR5380_hostdata *)(instance)->hostdata)->base = base;
 
-		if (NCR5380_init(instance, 0))
+		if (NCR5380_init(instance, FLAG_LATE_DMA_SETUP))
 			goto out_unregister;
 
 		NCR5380_maybe_reset_bus(instance);
Index: linux/drivers/scsi/g_NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/g_NCR5380.c	2016-03-23 21:09:37.000000000 +1100
+++ linux/drivers/scsi/g_NCR5380.c	2016-03-23 21:09:47.000000000 +1100
@@ -466,7 +466,7 @@ static int __init generic_NCR5380_detect
 		}
 #endif
 
-		if (NCR5380_init(instance, flags))
+		if (NCR5380_init(instance, flags | FLAG_LATE_DMA_SETUP))
 			goto out_unregister;
 
 		switch (overrides[current_override].board) {
Index: linux/drivers/scsi/pas16.c
===================================================================
--- linux.orig/drivers/scsi/pas16.c	2016-03-23 21:09:37.000000000 +1100
+++ linux/drivers/scsi/pas16.c	2016-03-23 21:09:47.000000000 +1100
@@ -375,7 +375,7 @@ static int __init pas16_detect(struct sc
 		
 	instance->io_port = io_port;
 
-	if (NCR5380_init(instance, FLAG_DMA_FIXUP))
+	if (NCR5380_init(instance, FLAG_DMA_FIXUP | FLAG_LATE_DMA_SETUP))
 		goto out_unregister;
 
 	NCR5380_maybe_reset_bus(instance);
Index: linux/drivers/scsi/t128.c
===================================================================
--- linux.orig/drivers/scsi/t128.c	2016-03-23 21:09:37.000000000 +1100
+++ linux/drivers/scsi/t128.c	2016-03-23 21:09:47.000000000 +1100
@@ -208,7 +208,7 @@ found:
 	instance->base = base;
 	((struct NCR5380_hostdata *)instance->hostdata)->base = p;
 
-	if (NCR5380_init(instance, FLAG_DMA_FIXUP))
+	if (NCR5380_init(instance, FLAG_DMA_FIXUP | FLAG_LATE_DMA_SETUP))
 		goto out_unregister;
 
 	NCR5380_maybe_reset_bus(instance);

^ permalink raw reply	[flat|nested] 60+ messages in thread

* [PATCH v4 10/23] ncr5380: Merge DMA implementation from atari_NCR5380 core driver
@ 2016-03-23 10:10   ` Finn Thain
  0 siblings, 0 replies; 60+ messages in thread
From: Finn Thain @ 2016-03-23 10:10 UTC (permalink / raw)
  To: James E.J. Bottomley, Martin K. Petersen, Michael Schmitz,
	linux-m68k, linux-scsi, linux-kernel, Russell King,
	linux-arm-kernel
  Cc: Sam Creasey, Ondrej Zary

[-- Attachment #1: ncr5380-merge-atari-dma-algorithm --]
[-- Type: text/plain, Size: 16359 bytes --]

Adopt the DMA implementation from atari_NCR5380.c. This means that
atari_scsi and sun3_scsi can make use of the NCR5380.c core driver
and the atari_NCR5380.c driver fork can be made redundant.

Signed-off-by: Finn Thain <fthain@telegraphics.com.au>
Reviewed-by: Hannes Reinecke <hare@suse.com>
Tested-by: Michael Schmitz <schmitzmic@gmail.com>
Tested-by: Ondrej Zary <linux@rainbow-software.org>

---
 drivers/scsi/NCR5380.c      |  170 +++++++++++++++++++++++++++++++++++---------
 drivers/scsi/arm/cumana_1.c |    3 
 drivers/scsi/arm/oak.c      |    3 
 drivers/scsi/dmx3191d.c     |    1 
 drivers/scsi/dtc.c          |    2 
 drivers/scsi/dtc.h          |    1 
 drivers/scsi/g_NCR5380.c    |    2 
 drivers/scsi/g_NCR5380.h    |    1 
 drivers/scsi/mac_scsi.c     |    3 
 drivers/scsi/pas16.c        |    2 
 drivers/scsi/pas16.h        |    1 
 drivers/scsi/t128.c         |    2 
 drivers/scsi/t128.h         |    1 
 13 files changed, 152 insertions(+), 40 deletions(-)

Index: linux/drivers/scsi/NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/NCR5380.c	2016-03-23 21:09:44.000000000 +1100
+++ linux/drivers/scsi/NCR5380.c	2016-03-23 21:09:47.000000000 +1100
@@ -31,9 +31,6 @@
 
 /*
  * Further development / testing that should be done :
- * 1.  Cleanup the NCR5380_transfer_dma function and DMA operation complete
- * code so that everything does the same thing that's done at the
- * end of a pseudo-DMA read operation.
  *
  * 4.  Test SCSI-II tagged queueing (I have no devices which support
  * tagged queueing)
@@ -117,6 +114,8 @@
  *
  * PSEUDO_DMA - if defined, PSEUDO DMA is used during the data transfer phases.
  *
+ * REAL_DMA - if defined, REAL DMA is used during the data transfer phases.
+ *
  * These macros MUST be defined :
  *
  * NCR5380_read(register)  - read from the specified register
@@ -801,6 +800,72 @@ static void NCR5380_main(struct work_str
 	} while (!done);
 }
 
+/*
+ * NCR5380_dma_complete - finish DMA transfer
+ * @instance: the scsi host instance
+ *
+ * Called by the interrupt handler when DMA finishes or a phase
+ * mismatch occurs (which would end the DMA transfer).
+ */
+
+static void NCR5380_dma_complete(struct Scsi_Host *instance)
+{
+	struct NCR5380_hostdata *hostdata = shost_priv(instance);
+	int transferred;
+	unsigned char **data;
+	int *count;
+	int saved_data = 0, overrun = 0;
+	unsigned char p;
+
+	if (hostdata->read_overruns) {
+		p = hostdata->connected->SCp.phase;
+		if (p & SR_IO) {
+			udelay(10);
+			if ((NCR5380_read(BUS_AND_STATUS_REG) &
+			     (BASR_PHASE_MATCH | BASR_ACK)) ==
+			    (BASR_PHASE_MATCH | BASR_ACK)) {
+				saved_data = NCR5380_read(INPUT_DATA_REG);
+				overrun = 1;
+				dsprintk(NDEBUG_DMA, instance, "read overrun handled\n");
+			}
+		}
+	}
+
+	NCR5380_write(MODE_REG, MR_BASE);
+	NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
+	NCR5380_read(RESET_PARITY_INTERRUPT_REG);
+
+	transferred = hostdata->dma_len - NCR5380_dma_residual(instance);
+	hostdata->dma_len = 0;
+
+	data = (unsigned char **)&hostdata->connected->SCp.ptr;
+	count = &hostdata->connected->SCp.this_residual;
+	*data += transferred;
+	*count -= transferred;
+
+	if (hostdata->read_overruns) {
+		int cnt, toPIO;
+
+		if ((NCR5380_read(STATUS_REG) & PHASE_MASK) == p && (p & SR_IO)) {
+			cnt = toPIO = hostdata->read_overruns;
+			if (overrun) {
+				dsprintk(NDEBUG_DMA, instance,
+				         "Got an input overrun, using saved byte\n");
+				*(*data)++ = saved_data;
+				(*count)--;
+				cnt--;
+				toPIO--;
+			}
+			if (toPIO > 0) {
+				dsprintk(NDEBUG_DMA, instance,
+				         "Doing %d byte PIO to 0x%p\n", cnt, *data);
+				NCR5380_transfer_pio(instance, &p, &cnt, data);
+				*count -= toPIO - cnt;
+			}
+		}
+	}
+}
+
 #ifndef DONT_USE_INTR
 
 /**
@@ -855,7 +920,22 @@ static irqreturn_t NCR5380_intr(int irq,
 		dsprintk(NDEBUG_INTR, instance, "IRQ %d, BASR 0x%02x, SR 0x%02x, MR 0x%02x\n",
 		         irq, basr, sr, mr);
 
-		if ((NCR5380_read(CURRENT_SCSI_DATA_REG) & hostdata->id_mask) &&
+		if ((mr & MR_DMA_MODE) || (mr & MR_MONITOR_BSY)) {
+			/* Probably End of DMA, Phase Mismatch or Loss of BSY.
+			 * We ack IRQ after clearing Mode Register. Workarounds
+			 * for End of DMA errata need to happen in DMA Mode.
+			 */
+
+			dsprintk(NDEBUG_INTR, instance, "interrupt in DMA mode\n");
+
+			if (hostdata->connected) {
+				NCR5380_dma_complete(instance);
+				queue_work(hostdata->work_q, &hostdata->main_task);
+			} else {
+				NCR5380_write(MODE_REG, MR_BASE);
+				NCR5380_read(RESET_PARITY_INTERRUPT_REG);
+			}
+		} else if ((NCR5380_read(CURRENT_SCSI_DATA_REG) & hostdata->id_mask) &&
 		    (sr & (SR_SEL | SR_IO | SR_BSY | SR_RST)) == (SR_SEL | SR_IO)) {
 			/* Probably reselected */
 			NCR5380_write(SELECT_ENABLE_REG, 0);
@@ -1431,28 +1511,38 @@ static int NCR5380_transfer_dma(struct S
 	register unsigned char p = *phase;
 	register unsigned char *d = *data;
 	unsigned char tmp;
-	int result;
+	int result = 0;
 
 	if ((tmp = (NCR5380_read(STATUS_REG) & PHASE_MASK)) != p) {
 		*phase = tmp;
 		return -1;
 	}
 
-	NCR5380_write(TARGET_COMMAND_REG, PHASE_SR_TO_TCR(p));
+	hostdata->connected->SCp.phase = p;
 
-	/*
-	 * Note : on my sample board, watch-dog timeouts occurred when interrupts
-	 * were not disabled for the duration of a single DMA transfer, from
-	 * before the setting of DMA mode to after transfer of the last byte.
-	 */
+	if (p & SR_IO) {
+		if (hostdata->read_overruns)
+			c -= hostdata->read_overruns;
+		else if (hostdata->flags & FLAG_DMA_FIXUP)
+			--c;
+	}
 
-	if (hostdata->flags & FLAG_DMA_FIXUP)
-		NCR5380_write(MODE_REG, MR_BASE | MR_DMA_MODE | MR_MONITOR_BSY);
-	else
-		NCR5380_write(MODE_REG, MR_BASE | MR_DMA_MODE | MR_MONITOR_BSY |
-		                        MR_ENABLE_EOP_INTR);
+	dsprintk(NDEBUG_DMA, instance, "initializing DMA %s: length %d, address %p\n",
+	         (p & SR_IO) ? "receive" : "send", c, d);
 
-	dprintk(NDEBUG_DMA, "scsi%d : mode reg = 0x%X\n", instance->host_no, NCR5380_read(MODE_REG));
+	NCR5380_write(TARGET_COMMAND_REG, PHASE_SR_TO_TCR(p));
+	NCR5380_write(MODE_REG, MR_BASE | MR_DMA_MODE | MR_MONITOR_BSY |
+	                        MR_ENABLE_EOP_INTR);
+
+	if (!(hostdata->flags & FLAG_LATE_DMA_SETUP)) {
+		/* On the Medusa, it is a must to initialize the DMA before
+		 * starting the NCR. This is also the cleaner way for the TT.
+		 */
+		if (p & SR_IO)
+			result = NCR5380_dma_recv_setup(instance, d, c);
+		else
+			result = NCR5380_dma_send_setup(instance, d, c);
+	}
 
 	/*
 	 * On the PAS16 at least I/O recovery delays are not needed here.
@@ -1470,6 +1560,29 @@ static int NCR5380_transfer_dma(struct S
 		NCR5380_io_delay(1);
 	}
 
+	if (hostdata->flags & FLAG_LATE_DMA_SETUP) {
+		/* On the Falcon, the DMA setup must be done after the last
+		 * NCR access, else the DMA setup gets trashed!
+		 */
+		if (p & SR_IO)
+			result = NCR5380_dma_recv_setup(instance, d, c);
+		else
+			result = NCR5380_dma_send_setup(instance, d, c);
+	}
+
+	/* On failure, NCR5380_dma_xxxx_setup() returns a negative int. */
+	if (result < 0)
+		return result;
+
+	/* For real DMA, result is the byte count. DMA interrupt is expected. */
+	if (result > 0) {
+		hostdata->dma_len = result;
+		return 0;
+	}
+
+	/* The result is zero iff pseudo DMA send/receive was completed. */
+	hostdata->dma_len = c;
+
 /*
  * A note regarding the DMA errata workarounds for early NMOS silicon.
  *
@@ -1504,10 +1617,8 @@ static int NCR5380_transfer_dma(struct S
  * request.
  */
 
-	if (p & SR_IO) {
-		result = NCR5380_dma_recv_setup(instance, d,
-			hostdata->flags & FLAG_DMA_FIXUP ? c - 1 : c);
-		if (!result && (hostdata->flags & FLAG_DMA_FIXUP)) {
+	if (hostdata->flags & FLAG_DMA_FIXUP) {
+		if (p & SR_IO) {
 			/*
 			 * The workaround was to transfer fewer bytes than we
 			 * intended to with the pseudo-DMA read function, wait for
@@ -1533,11 +1644,8 @@ static int NCR5380_transfer_dma(struct S
 				result = -1;
 				shost_printk(KERN_ERR, instance, "PDMA read: !REQ timeout\n");
 			}
-			d[c - 1] = NCR5380_read(INPUT_DATA_REG);
-		}
-	} else {
-		result = NCR5380_dma_send_setup(instance, d, c);
-		if (!result && (hostdata->flags & FLAG_DMA_FIXUP)) {
+			d[*count - 1] = NCR5380_read(INPUT_DATA_REG);
+		} else {
 			/*
 			 * Wait for the last byte to be sent.  If REQ is being asserted for
 			 * the byte we're interested, we'll ACK it and it will go false.
@@ -1550,11 +1658,8 @@ static int NCR5380_transfer_dma(struct S
 			}
 		}
 	}
-	NCR5380_write(MODE_REG, MR_BASE);
-	NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
-	NCR5380_read(RESET_PARITY_INTERRUPT_REG);
-	*data = d + c;
-	*count = 0;
+
+	NCR5380_dma_complete(instance);
 	return result;
 }
 
@@ -1667,8 +1772,7 @@ static void NCR5380_information_transfer
 						do_abort(instance);
 						cmd->result = DID_ERROR << 16;
 						/* XXX - need to source or sink data here, as appropriate */
-					} else
-						cmd->SCp.this_residual -= transfersize - len;
+					}
 				} else {
 					/* Break up transfer into 3 ms chunks,
 					 * presuming 6 accesses per handshake.
Index: linux/drivers/scsi/arm/cumana_1.c
===================================================================
--- linux.orig/drivers/scsi/arm/cumana_1.c	2016-03-23 21:09:44.000000000 +1100
+++ linux/drivers/scsi/arm/cumana_1.c	2016-03-23 21:09:47.000000000 +1100
@@ -20,6 +20,7 @@
 #define NCR5380_dma_xfer_len(instance, cmd, phase)	(cmd->transfersize)
 #define NCR5380_dma_recv_setup		cumanascsi_pread
 #define NCR5380_dma_send_setup		cumanascsi_pwrite
+#define NCR5380_dma_residual(instance)	(0)
 
 #define NCR5380_intr			cumanascsi_intr
 #define NCR5380_queue_command		cumanascsi_queue_command
@@ -245,7 +246,7 @@ static int cumanascsi1_probe(struct expa
 
 	host->irq = ec->irq;
 
-	ret = NCR5380_init(host, FLAG_DMA_FIXUP);
+	ret = NCR5380_init(host, FLAG_DMA_FIXUP | FLAG_LATE_DMA_SETUP);
 	if (ret)
 		goto out_unmap;
 
Index: linux/drivers/scsi/arm/oak.c
===================================================================
--- linux.orig/drivers/scsi/arm/oak.c	2016-03-23 21:09:44.000000000 +1100
+++ linux/drivers/scsi/arm/oak.c	2016-03-23 21:09:47.000000000 +1100
@@ -26,6 +26,7 @@
 #define NCR5380_dma_xfer_len(instance, cmd, phase)	(0)
 #define NCR5380_dma_recv_setup		oakscsi_pread
 #define NCR5380_dma_send_setup		oakscsi_pwrite
+#define NCR5380_dma_residual(instance)	(0)
 
 #define NCR5380_queue_command		oakscsi_queue_command
 #define NCR5380_info			oakscsi_info
@@ -144,7 +145,7 @@ static int oakscsi_probe(struct expansio
 	host->irq = NO_IRQ;
 	host->n_io_port = 255;
 
-	ret = NCR5380_init(host, FLAG_DMA_FIXUP);
+	ret = NCR5380_init(host, FLAG_DMA_FIXUP | FLAG_LATE_DMA_SETUP);
 	if (ret)
 		goto out_unmap;
 
Index: linux/drivers/scsi/dmx3191d.c
===================================================================
--- linux.orig/drivers/scsi/dmx3191d.c	2016-03-23 21:09:37.000000000 +1100
+++ linux/drivers/scsi/dmx3191d.c	2016-03-23 21:09:47.000000000 +1100
@@ -42,6 +42,7 @@
 #define NCR5380_dma_xfer_len(instance, cmd, phase)	(0)
 #define NCR5380_dma_recv_setup(instance, dst, len)	(0)
 #define NCR5380_dma_send_setup(instance, src, len)	(0)
+#define NCR5380_dma_residual(instance)			(0)
 
 #define NCR5380_implementation_fields	/* none */
 
Index: linux/drivers/scsi/dtc.h
===================================================================
--- linux.orig/drivers/scsi/dtc.h	2016-03-23 21:09:37.000000000 +1100
+++ linux/drivers/scsi/dtc.h	2016-03-23 21:09:47.000000000 +1100
@@ -23,6 +23,7 @@
         dtc_dma_xfer_len(cmd)
 #define NCR5380_dma_recv_setup		dtc_pread
 #define NCR5380_dma_send_setup		dtc_pwrite
+#define NCR5380_dma_residual(instance)	(0)
 
 #define NCR5380_intr			dtc_intr
 #define NCR5380_queue_command		dtc_queue_command
Index: linux/drivers/scsi/g_NCR5380.h
===================================================================
--- linux.orig/drivers/scsi/g_NCR5380.h	2016-03-23 21:09:37.000000000 +1100
+++ linux/drivers/scsi/g_NCR5380.h	2016-03-23 21:09:47.000000000 +1100
@@ -64,6 +64,7 @@
         generic_NCR5380_dma_xfer_len(instance, cmd)
 #define NCR5380_dma_recv_setup		generic_NCR5380_pread
 #define NCR5380_dma_send_setup		generic_NCR5380_pwrite
+#define NCR5380_dma_residual(instance)	(0)
 
 #define NCR5380_intr generic_NCR5380_intr
 #define NCR5380_queue_command generic_NCR5380_queue_command
Index: linux/drivers/scsi/mac_scsi.c
===================================================================
--- linux.orig/drivers/scsi/mac_scsi.c	2016-03-23 21:09:37.000000000 +1100
+++ linux/drivers/scsi/mac_scsi.c	2016-03-23 21:09:47.000000000 +1100
@@ -37,6 +37,7 @@
         macscsi_dma_xfer_len(instance, cmd)
 #define NCR5380_dma_recv_setup          macscsi_pread
 #define NCR5380_dma_send_setup          macscsi_pwrite
+#define NCR5380_dma_residual(instance)  (0)
 
 #define NCR5380_intr                    macscsi_intr
 #define NCR5380_queue_command           macscsi_queue_command
@@ -386,7 +387,7 @@ static int __init mac_scsi_probe(struct
 #endif
 	host_flags |= setup_toshiba_delay > 0 ? FLAG_TOSHIBA_DELAY : 0;
 
-	error = NCR5380_init(instance, host_flags);
+	error = NCR5380_init(instance, host_flags | FLAG_LATE_DMA_SETUP);
 	if (error)
 		goto fail_init;
 
Index: linux/drivers/scsi/pas16.h
===================================================================
--- linux.orig/drivers/scsi/pas16.h	2016-03-23 21:09:37.000000000 +1100
+++ linux/drivers/scsi/pas16.h	2016-03-23 21:09:47.000000000 +1100
@@ -105,6 +105,7 @@
 #define NCR5380_dma_xfer_len(instance, cmd, phase)	(cmd->transfersize)
 #define NCR5380_dma_recv_setup		pas16_pread
 #define NCR5380_dma_send_setup		pas16_pwrite
+#define NCR5380_dma_residual(instance)	(0)
 
 #define NCR5380_intr pas16_intr
 #define NCR5380_queue_command pas16_queue_command
Index: linux/drivers/scsi/t128.h
===================================================================
--- linux.orig/drivers/scsi/t128.h	2016-03-23 21:09:37.000000000 +1100
+++ linux/drivers/scsi/t128.h	2016-03-23 21:09:47.000000000 +1100
@@ -79,6 +79,7 @@
 #define NCR5380_dma_xfer_len(instance, cmd, phase)	(cmd->transfersize)
 #define NCR5380_dma_recv_setup		t128_pread
 #define NCR5380_dma_send_setup		t128_pwrite
+#define NCR5380_dma_residual(instance)	(0)
 
 #define NCR5380_intr t128_intr
 #define NCR5380_queue_command t128_queue_command
Index: linux/drivers/scsi/dtc.c
===================================================================
--- linux.orig/drivers/scsi/dtc.c	2016-03-23 21:09:37.000000000 +1100
+++ linux/drivers/scsi/dtc.c	2016-03-23 21:09:47.000000000 +1100
@@ -228,7 +228,7 @@ found:
 		instance->base = addr;
 		((struct NCR5380_hostdata *)(instance)->hostdata)->base = base;
 
-		if (NCR5380_init(instance, 0))
+		if (NCR5380_init(instance, FLAG_LATE_DMA_SETUP))
 			goto out_unregister;
 
 		NCR5380_maybe_reset_bus(instance);
Index: linux/drivers/scsi/g_NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/g_NCR5380.c	2016-03-23 21:09:37.000000000 +1100
+++ linux/drivers/scsi/g_NCR5380.c	2016-03-23 21:09:47.000000000 +1100
@@ -466,7 +466,7 @@ static int __init generic_NCR5380_detect
 		}
 #endif
 
-		if (NCR5380_init(instance, flags))
+		if (NCR5380_init(instance, flags | FLAG_LATE_DMA_SETUP))
 			goto out_unregister;
 
 		switch (overrides[current_override].board) {
Index: linux/drivers/scsi/pas16.c
===================================================================
--- linux.orig/drivers/scsi/pas16.c	2016-03-23 21:09:37.000000000 +1100
+++ linux/drivers/scsi/pas16.c	2016-03-23 21:09:47.000000000 +1100
@@ -375,7 +375,7 @@ static int __init pas16_detect(struct sc
 		
 	instance->io_port = io_port;
 
-	if (NCR5380_init(instance, FLAG_DMA_FIXUP))
+	if (NCR5380_init(instance, FLAG_DMA_FIXUP | FLAG_LATE_DMA_SETUP))
 		goto out_unregister;
 
 	NCR5380_maybe_reset_bus(instance);
Index: linux/drivers/scsi/t128.c
===================================================================
--- linux.orig/drivers/scsi/t128.c	2016-03-23 21:09:37.000000000 +1100
+++ linux/drivers/scsi/t128.c	2016-03-23 21:09:47.000000000 +1100
@@ -208,7 +208,7 @@ found:
 	instance->base = base;
 	((struct NCR5380_hostdata *)instance->hostdata)->base = p;
 
-	if (NCR5380_init(instance, FLAG_DMA_FIXUP))
+	if (NCR5380_init(instance, FLAG_DMA_FIXUP | FLAG_LATE_DMA_SETUP))
 		goto out_unregister;
 
 	NCR5380_maybe_reset_bus(instance);

^ permalink raw reply	[flat|nested] 60+ messages in thread

* [PATCH v4 10/23] ncr5380: Merge DMA implementation from atari_NCR5380 core driver
@ 2016-03-23 10:10   ` Finn Thain
  0 siblings, 0 replies; 60+ messages in thread
From: Finn Thain @ 2016-03-23 10:10 UTC (permalink / raw)
  To: linux-arm-kernel

An embedded and charset-unspecified text was scrubbed...
Name: ncr5380-merge-atari-dma-algorithm
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20160323/bc43ba16/attachment.ksh>

^ permalink raw reply	[flat|nested] 60+ messages in thread

* [PATCH v4 11/23] atari_scsi: Adopt NCR5380.c core driver
  2016-03-23 10:10 ` Finn Thain
@ 2016-03-23 10:10   ` Finn Thain
  -1 siblings, 0 replies; 60+ messages in thread
From: Finn Thain @ 2016-03-23 10:10 UTC (permalink / raw)
  To: James E.J. Bottomley, Martin K. Petersen, Michael Schmitz,
	linux-m68k, linux-scsi, linux-kernel
  Cc: Ondrej Zary, Sam Creasey

[-- Attachment #1: atari_scsi-adopt-NCR5380-c --]
[-- Type: text/plain, Size: 4480 bytes --]

Add support for the Atari ST DMA chip to the NCR5380.c core driver.
This code is copied from atari_NCR5380.c.

Signed-off-by: Finn Thain <fthain@telegraphics.com.au>
Reviewed-by: Hannes Reinecke <hare@suse.com>
Tested-by: Michael Schmitz <schmitzmic@gmail.com>
Tested-by: Ondrej Zary <linux@rainbow-software.org>

---
 drivers/scsi/NCR5380.c    |   32 ++++++++++++++++++++++++++++++++
 drivers/scsi/atari_scsi.c |    6 +++---
 2 files changed, 35 insertions(+), 3 deletions(-)

Index: linux/drivers/scsi/NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/NCR5380.c	2016-03-23 21:09:47.000000000 +1100
+++ linux/drivers/scsi/NCR5380.c	2016-03-23 21:09:51.000000000 +1100
@@ -29,6 +29,8 @@
  * Ronald van Cuijlenborg, Alan Cox and others.
  */
 
+/* Ported to Atari by Roman Hodek and others. */
+
 /*
  * Further development / testing that should be done :
  *
@@ -141,6 +143,14 @@
 #define NCR5380_io_delay(x)
 #endif
 
+#ifndef NCR5380_acquire_dma_irq
+#define NCR5380_acquire_dma_irq(x)	(1)
+#endif
+
+#ifndef NCR5380_release_dma_irq
+#define NCR5380_release_dma_irq(x)
+#endif
+
 static int do_abort(struct Scsi_Host *);
 static void do_reset(struct Scsi_Host *);
 
@@ -658,6 +668,9 @@ static int NCR5380_queue_command(struct
 
 	cmd->result = 0;
 
+	if (!NCR5380_acquire_dma_irq(instance))
+		return SCSI_MLQUEUE_HOST_BUSY;
+
 	spin_lock_irqsave(&hostdata->lock, flags);
 
 	/*
@@ -682,6 +695,19 @@ static int NCR5380_queue_command(struct
 	return 0;
 }
 
+static inline void maybe_release_dma_irq(struct Scsi_Host *instance)
+{
+	struct NCR5380_hostdata *hostdata = shost_priv(instance);
+
+	/* Caller does the locking needed to set & test these data atomically */
+	if (list_empty(&hostdata->disconnected) &&
+	    list_empty(&hostdata->unissued) &&
+	    list_empty(&hostdata->autosense) &&
+	    !hostdata->connected &&
+	    !hostdata->selecting)
+		NCR5380_release_dma_irq(instance);
+}
+
 /**
  * dequeue_next_cmd - dequeue a command for processing
  * @instance: the scsi host instance
@@ -783,6 +809,7 @@ static void NCR5380_main(struct work_str
 
 			if (!NCR5380_select(instance, cmd)) {
 				dsprintk(NDEBUG_MAIN, instance, "main: select complete\n");
+				maybe_release_dma_irq(instance);
 			} else {
 				dsprintk(NDEBUG_MAIN | NDEBUG_QUEUES, instance,
 				         "main: select failed, returning %p to queue\n", cmd);
@@ -1828,6 +1855,8 @@ static void NCR5380_information_transfer
 
 					/* Enable reselect interrupts */
 					NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
+
+					maybe_release_dma_irq(instance);
 					return;
 				case MESSAGE_REJECT:
 					/* Accept message by clearing ACK */
@@ -1963,6 +1992,7 @@ static void NCR5380_information_transfer
 					hostdata->connected = NULL;
 					cmd->result = DID_ERROR << 16;
 					complete_cmd(instance, cmd);
+					maybe_release_dma_irq(instance);
 					NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
 					return;
 				}
@@ -2256,6 +2286,7 @@ out:
 		dsprintk(NDEBUG_ABORT, instance, "abort: successfully aborted %p\n", cmd);
 
 	queue_work(hostdata->work_q, &hostdata->main_task);
+	maybe_release_dma_irq(instance);
 	spin_unlock_irqrestore(&hostdata->lock, flags);
 
 	return result;
@@ -2336,6 +2367,7 @@ static int NCR5380_bus_reset(struct scsi
 	hostdata->dma_len = 0;
 
 	queue_work(hostdata->work_q, &hostdata->main_task);
+	maybe_release_dma_irq(instance);
 	spin_unlock_irqrestore(&hostdata->lock, flags);
 
 	return SUCCESS;
Index: linux/drivers/scsi/atari_scsi.c
===================================================================
--- linux.orig/drivers/scsi/atari_scsi.c	2016-03-23 21:09:44.000000000 +1100
+++ linux/drivers/scsi/atari_scsi.c	2016-03-23 21:09:51.000000000 +1100
@@ -99,9 +99,9 @@
 #define NCR5380_abort                   atari_scsi_abort
 #define NCR5380_info                    atari_scsi_info
 
-#define NCR5380_dma_read_setup(instance, data, count) \
+#define NCR5380_dma_recv_setup(instance, data, count) \
         atari_scsi_dma_setup(instance, data, count, 0)
-#define NCR5380_dma_write_setup(instance, data, count) \
+#define NCR5380_dma_send_setup(instance, data, count) \
         atari_scsi_dma_setup(instance, data, count, 1)
 #define NCR5380_dma_residual(instance) \
         atari_scsi_dma_residual(instance)
@@ -715,7 +715,7 @@ static void atari_scsi_falcon_reg_write(
 }
 
 
-#include "atari_NCR5380.c"
+#include "NCR5380.c"
 
 static int atari_scsi_bus_reset(struct scsi_cmnd *cmd)
 {

^ permalink raw reply	[flat|nested] 60+ messages in thread

* [PATCH v4 11/23] atari_scsi: Adopt NCR5380.c core driver
@ 2016-03-23 10:10   ` Finn Thain
  0 siblings, 0 replies; 60+ messages in thread
From: Finn Thain @ 2016-03-23 10:10 UTC (permalink / raw)
  To: James E.J. Bottomley, Martin K. Petersen, Michael Schmitz,
	linux-m68k, linux-scsi, linux-kernel
  Cc: Ondrej Zary, Sam Creasey

[-- Attachment #1: atari_scsi-adopt-NCR5380-c --]
[-- Type: text/plain, Size: 4480 bytes --]

Add support for the Atari ST DMA chip to the NCR5380.c core driver.
This code is copied from atari_NCR5380.c.

Signed-off-by: Finn Thain <fthain@telegraphics.com.au>
Reviewed-by: Hannes Reinecke <hare@suse.com>
Tested-by: Michael Schmitz <schmitzmic@gmail.com>
Tested-by: Ondrej Zary <linux@rainbow-software.org>

---
 drivers/scsi/NCR5380.c    |   32 ++++++++++++++++++++++++++++++++
 drivers/scsi/atari_scsi.c |    6 +++---
 2 files changed, 35 insertions(+), 3 deletions(-)

Index: linux/drivers/scsi/NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/NCR5380.c	2016-03-23 21:09:47.000000000 +1100
+++ linux/drivers/scsi/NCR5380.c	2016-03-23 21:09:51.000000000 +1100
@@ -29,6 +29,8 @@
  * Ronald van Cuijlenborg, Alan Cox and others.
  */
 
+/* Ported to Atari by Roman Hodek and others. */
+
 /*
  * Further development / testing that should be done :
  *
@@ -141,6 +143,14 @@
 #define NCR5380_io_delay(x)
 #endif
 
+#ifndef NCR5380_acquire_dma_irq
+#define NCR5380_acquire_dma_irq(x)	(1)
+#endif
+
+#ifndef NCR5380_release_dma_irq
+#define NCR5380_release_dma_irq(x)
+#endif
+
 static int do_abort(struct Scsi_Host *);
 static void do_reset(struct Scsi_Host *);
 
@@ -658,6 +668,9 @@ static int NCR5380_queue_command(struct
 
 	cmd->result = 0;
 
+	if (!NCR5380_acquire_dma_irq(instance))
+		return SCSI_MLQUEUE_HOST_BUSY;
+
 	spin_lock_irqsave(&hostdata->lock, flags);
 
 	/*
@@ -682,6 +695,19 @@ static int NCR5380_queue_command(struct
 	return 0;
 }
 
+static inline void maybe_release_dma_irq(struct Scsi_Host *instance)
+{
+	struct NCR5380_hostdata *hostdata = shost_priv(instance);
+
+	/* Caller does the locking needed to set & test these data atomically */
+	if (list_empty(&hostdata->disconnected) &&
+	    list_empty(&hostdata->unissued) &&
+	    list_empty(&hostdata->autosense) &&
+	    !hostdata->connected &&
+	    !hostdata->selecting)
+		NCR5380_release_dma_irq(instance);
+}
+
 /**
  * dequeue_next_cmd - dequeue a command for processing
  * @instance: the scsi host instance
@@ -783,6 +809,7 @@ static void NCR5380_main(struct work_str
 
 			if (!NCR5380_select(instance, cmd)) {
 				dsprintk(NDEBUG_MAIN, instance, "main: select complete\n");
+				maybe_release_dma_irq(instance);
 			} else {
 				dsprintk(NDEBUG_MAIN | NDEBUG_QUEUES, instance,
 				         "main: select failed, returning %p to queue\n", cmd);
@@ -1828,6 +1855,8 @@ static void NCR5380_information_transfer
 
 					/* Enable reselect interrupts */
 					NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
+
+					maybe_release_dma_irq(instance);
 					return;
 				case MESSAGE_REJECT:
 					/* Accept message by clearing ACK */
@@ -1963,6 +1992,7 @@ static void NCR5380_information_transfer
 					hostdata->connected = NULL;
 					cmd->result = DID_ERROR << 16;
 					complete_cmd(instance, cmd);
+					maybe_release_dma_irq(instance);
 					NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
 					return;
 				}
@@ -2256,6 +2286,7 @@ out:
 		dsprintk(NDEBUG_ABORT, instance, "abort: successfully aborted %p\n", cmd);
 
 	queue_work(hostdata->work_q, &hostdata->main_task);
+	maybe_release_dma_irq(instance);
 	spin_unlock_irqrestore(&hostdata->lock, flags);
 
 	return result;
@@ -2336,6 +2367,7 @@ static int NCR5380_bus_reset(struct scsi
 	hostdata->dma_len = 0;
 
 	queue_work(hostdata->work_q, &hostdata->main_task);
+	maybe_release_dma_irq(instance);
 	spin_unlock_irqrestore(&hostdata->lock, flags);
 
 	return SUCCESS;
Index: linux/drivers/scsi/atari_scsi.c
===================================================================
--- linux.orig/drivers/scsi/atari_scsi.c	2016-03-23 21:09:44.000000000 +1100
+++ linux/drivers/scsi/atari_scsi.c	2016-03-23 21:09:51.000000000 +1100
@@ -99,9 +99,9 @@
 #define NCR5380_abort                   atari_scsi_abort
 #define NCR5380_info                    atari_scsi_info
 
-#define NCR5380_dma_read_setup(instance, data, count) \
+#define NCR5380_dma_recv_setup(instance, data, count) \
         atari_scsi_dma_setup(instance, data, count, 0)
-#define NCR5380_dma_write_setup(instance, data, count) \
+#define NCR5380_dma_send_setup(instance, data, count) \
         atari_scsi_dma_setup(instance, data, count, 1)
 #define NCR5380_dma_residual(instance) \
         atari_scsi_dma_residual(instance)
@@ -715,7 +715,7 @@ static void atari_scsi_falcon_reg_write(
 }
 
 
-#include "atari_NCR5380.c"
+#include "NCR5380.c"
 
 static int atari_scsi_bus_reset(struct scsi_cmnd *cmd)
 {

^ permalink raw reply	[flat|nested] 60+ messages in thread

* [PATCH v4 12/23] sun3_scsi: Adopt NCR5380.c core driver
  2016-03-23 10:10 ` Finn Thain
@ 2016-03-23 10:10   ` Finn Thain
  -1 siblings, 0 replies; 60+ messages in thread
From: Finn Thain @ 2016-03-23 10:10 UTC (permalink / raw)
  To: James E.J. Bottomley, Martin K. Petersen, Michael Schmitz,
	linux-m68k, linux-scsi, linux-kernel
  Cc: Ondrej Zary, Sam Creasey

[-- Attachment #1: sun3_scsi-adopt-NCR5380-c --]
[-- Type: text/plain, Size: 8544 bytes --]

Add support for the custom Sun 3 DMA logic to the NCR5380.c core driver.
This code is copied from atari_NCR5380.c.

Signed-off-by: Finn Thain <fthain@telegraphics.com.au>
Reviewed-by: Hannes Reinecke <hare@suse.com>
Tested-by: Michael Schmitz <schmitzmic@gmail.com>
Tested-by: Ondrej Zary <linux@rainbow-software.org>

---

The Sun 3 DMA code is still configured by macros. I have simplified things
slightly but I have avoided more ambitious refactoring. It's not clear to
me what that should look like and I can't test sun3_scsi anyway. At least
this permits the removal of atari_NCR5380.c.

---
 drivers/scsi/NCR5380.c   |  131 +++++++++++++++++++++++++++++++++++++++++++----
 drivers/scsi/sun3_scsi.c |    8 +-
 2 files changed, 124 insertions(+), 15 deletions(-)

Index: linux/drivers/scsi/sun3_scsi.c
===================================================================
--- linux.orig/drivers/scsi/sun3_scsi.c	2016-03-23 21:09:24.000000000 +1100
+++ linux/drivers/scsi/sun3_scsi.c	2016-03-23 21:09:52.000000000 +1100
@@ -54,10 +54,8 @@
 #define NCR5380_abort                   sun3scsi_abort
 #define NCR5380_info                    sun3scsi_info
 
-#define NCR5380_dma_read_setup(instance, data, count) \
-        sun3scsi_dma_setup(instance, data, count, 0)
-#define NCR5380_dma_write_setup(instance, data, count) \
-        sun3scsi_dma_setup(instance, data, count, 1)
+#define NCR5380_dma_recv_setup(instance, data, count) (count)
+#define NCR5380_dma_send_setup(instance, data, count) (count)
 #define NCR5380_dma_residual(instance) \
         sun3scsi_dma_residual(instance)
 #define NCR5380_dma_xfer_len(instance, cmd, phase) \
@@ -406,7 +404,7 @@ static int sun3scsi_dma_finish(int write
 
 }
 	
-#include "atari_NCR5380.c"
+#include "NCR5380.c"
 
 #ifdef SUN3_SCSI_VME
 #define SUN3_SCSI_NAME          "Sun3 NCR5380 VME SCSI"
Index: linux/drivers/scsi/NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/NCR5380.c	2016-03-23 21:09:51.000000000 +1100
+++ linux/drivers/scsi/NCR5380.c	2016-03-23 21:09:52.000000000 +1100
@@ -31,6 +31,8 @@
 
 /* Ported to Atari by Roman Hodek and others. */
 
+/* Adapted for the Sun 3 by Sam Creasey. */
+
 /*
  * Further development / testing that should be done :
  *
@@ -858,6 +860,23 @@ static void NCR5380_dma_complete(struct
 		}
 	}
 
+#ifdef CONFIG_SUN3
+	if ((sun3scsi_dma_finish(rq_data_dir(hostdata->connected->request)))) {
+		pr_err("scsi%d: overrun in UDC counter -- not prepared to deal with this!\n",
+		       instance->host_no);
+		BUG();
+	}
+
+	if ((NCR5380_read(BUS_AND_STATUS_REG) & (BASR_PHASE_MATCH | BASR_ACK)) ==
+	    (BASR_PHASE_MATCH | BASR_ACK)) {
+		pr_err("scsi%d: BASR %02x\n", instance->host_no,
+		       NCR5380_read(BUS_AND_STATUS_REG));
+		pr_err("scsi%d: bus stuck in data phase -- probably a single byte overrun!\n",
+		       instance->host_no);
+		BUG();
+	}
+#endif
+
 	NCR5380_write(MODE_REG, MR_BASE);
 	NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
 	NCR5380_read(RESET_PARITY_INTERRUPT_REG);
@@ -981,10 +1000,16 @@ static irqreturn_t NCR5380_intr(int irq,
 			NCR5380_read(RESET_PARITY_INTERRUPT_REG);
 
 			dsprintk(NDEBUG_INTR, instance, "unknown interrupt\n");
+#ifdef SUN3_SCSI_VME
+			dregs->csr |= CSR_DMA_ENABLE;
+#endif
 		}
 		handled = 1;
 	} else {
 		shost_printk(KERN_NOTICE, instance, "interrupt without IRQ bit\n");
+#ifdef SUN3_SCSI_VME
+		dregs->csr |= CSR_DMA_ENABLE;
+#endif
 	}
 
 	spin_unlock_irqrestore(&hostdata->lock, flags);
@@ -1274,6 +1299,10 @@ static struct scsi_cmnd *NCR5380_select(
 	hostdata->connected = cmd;
 	hostdata->busy[cmd->device->id] |= 1 << cmd->device->lun;
 
+#ifdef SUN3_SCSI_VME
+	dregs->csr |= CSR_INTR;
+#endif
+
 	initialize_SCp(cmd);
 
 	cmd = NULL;
@@ -1557,6 +1586,11 @@ static int NCR5380_transfer_dma(struct S
 	dsprintk(NDEBUG_DMA, instance, "initializing DMA %s: length %d, address %p\n",
 	         (p & SR_IO) ? "receive" : "send", c, d);
 
+#ifdef CONFIG_SUN3
+	/* send start chain */
+	sun3scsi_dma_start(c, *data);
+#endif
+
 	NCR5380_write(TARGET_COMMAND_REG, PHASE_SR_TO_TCR(p));
 	NCR5380_write(MODE_REG, MR_BASE | MR_DMA_MODE | MR_MONITOR_BSY |
 	                        MR_ENABLE_EOP_INTR);
@@ -1577,6 +1611,7 @@ static int NCR5380_transfer_dma(struct S
 	 */
 
 	if (p & SR_IO) {
+		NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
 		NCR5380_io_delay(1);
 		NCR5380_write(START_DMA_INITIATOR_RECEIVE_REG, 0);
 	} else {
@@ -1587,6 +1622,13 @@ static int NCR5380_transfer_dma(struct S
 		NCR5380_io_delay(1);
 	}
 
+#ifdef CONFIG_SUN3
+#ifdef SUN3_SCSI_VME
+	dregs->csr |= CSR_DMA_ENABLE;
+#endif
+	sun3_dma_active = 1;
+#endif
+
 	if (hostdata->flags & FLAG_LATE_DMA_SETUP) {
 		/* On the Falcon, the DMA setup must be done after the last
 		 * NCR access, else the DMA setup gets trashed!
@@ -1718,6 +1760,10 @@ static void NCR5380_information_transfer
 	unsigned char phase, tmp, extended_msg[10], old_phase = 0xff;
 	struct scsi_cmnd *cmd;
 
+#ifdef SUN3_SCSI_VME
+	dregs->csr |= CSR_INTR;
+#endif
+
 	while ((cmd = hostdata->connected)) {
 		struct NCR5380_cmd *ncmd = scsi_cmd_priv(cmd);
 
@@ -1729,6 +1775,31 @@ static void NCR5380_information_transfer
 				old_phase = phase;
 				NCR5380_dprint_phase(NDEBUG_INFORMATION, instance);
 			}
+#ifdef CONFIG_SUN3
+			if (phase == PHASE_CMDOUT) {
+				void *d;
+				unsigned long count;
+
+				if (!cmd->SCp.this_residual && cmd->SCp.buffers_residual) {
+					count = cmd->SCp.buffer->length;
+					d = sg_virt(cmd->SCp.buffer);
+				} else {
+					count = cmd->SCp.this_residual;
+					d = cmd->SCp.ptr;
+				}
+
+				if (sun3_dma_setup_done != cmd &&
+				    sun3scsi_dma_xfer_len(count, cmd) > 0) {
+					sun3scsi_dma_setup(instance, d, count,
+					                   rq_data_dir(cmd->request));
+					sun3_dma_setup_done = cmd;
+				}
+#ifdef SUN3_SCSI_VME
+				dregs->csr |= CSR_INTR;
+#endif
+			}
+#endif /* CONFIG_SUN3 */
+
 			if (sink && (phase != PHASE_MSGOUT)) {
 				NCR5380_write(TARGET_COMMAND_REG, PHASE_SR_TO_TCR(tmp));
 
@@ -1811,6 +1882,10 @@ static void NCR5380_information_transfer
 					                     (unsigned char **)&cmd->SCp.ptr);
 					cmd->SCp.this_residual -= transfersize - len;
 				}
+#ifdef CONFIG_SUN3
+				if (sun3_dma_setup_done == cmd)
+					sun3_dma_setup_done = NULL;
+#endif
 				return;
 			case PHASE_MSGIN:
 				len = 1;
@@ -1889,6 +1964,9 @@ static void NCR5380_information_transfer
 
 					/* Enable reselect interrupts */
 					NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
+#ifdef SUN3_SCSI_VME
+					dregs->csr |= CSR_DMA_ENABLE;
+#endif
 					return;
 					/*
 					 * The SCSI data pointer is *IMPLICITLY* saved on a disconnect
@@ -2040,10 +2118,8 @@ static void NCR5380_reselect(struct Scsi
 {
 	struct NCR5380_hostdata *hostdata = shost_priv(instance);
 	unsigned char target_mask;
-	unsigned char lun, phase;
-	int len;
+	unsigned char lun;
 	unsigned char msg[3];
-	unsigned char *data;
 	struct NCR5380_cmd *ncmd;
 	struct scsi_cmnd *tmp;
 
@@ -2085,15 +2161,26 @@ static void NCR5380_reselect(struct Scsi
 		return;
 	}
 
-	len = 1;
-	data = msg;
-	phase = PHASE_MSGIN;
-	NCR5380_transfer_pio(instance, &phase, &len, &data);
+#ifdef CONFIG_SUN3
+	/* acknowledge toggle to MSGIN */
+	NCR5380_write(TARGET_COMMAND_REG, PHASE_SR_TO_TCR(PHASE_MSGIN));
+
+	/* peek at the byte without really hitting the bus */
+	msg[0] = NCR5380_read(CURRENT_SCSI_DATA_REG);
+#else
+	{
+		int len = 1;
+		unsigned char *data = msg;
+		unsigned char phase = PHASE_MSGIN;
 
-	if (len) {
-		do_abort(instance);
-		return;
+		NCR5380_transfer_pio(instance, &phase, &len, &data);
+
+		if (len) {
+			do_abort(instance);
+			return;
+		}
 	}
+#endif /* CONFIG_SUN3 */
 
 	if (!(msg[0] & 0x80)) {
 		shost_printk(KERN_ERR, instance, "expecting IDENTIFY message, got ");
@@ -2141,6 +2228,30 @@ static void NCR5380_reselect(struct Scsi
 		return;
 	}
 
+#ifdef CONFIG_SUN3
+	{
+		void *d;
+		unsigned long count;
+
+		if (!tmp->SCp.this_residual && tmp->SCp.buffers_residual) {
+			count = tmp->SCp.buffer->length;
+			d = sg_virt(tmp->SCp.buffer);
+		} else {
+			count = tmp->SCp.this_residual;
+			d = tmp->SCp.ptr;
+		}
+
+		if (sun3_dma_setup_done != tmp &&
+		    sun3scsi_dma_xfer_len(count, tmp) > 0) {
+			sun3scsi_dma_setup(instance, d, count,
+			                   rq_data_dir(tmp->request));
+			sun3_dma_setup_done = tmp;
+		}
+	}
+
+	NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_ACK);
+#endif /* CONFIG_SUN3 */
+
 	/* Accept message by clearing ACK */
 	NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
 

^ permalink raw reply	[flat|nested] 60+ messages in thread

* [PATCH v4 12/23] sun3_scsi: Adopt NCR5380.c core driver
@ 2016-03-23 10:10   ` Finn Thain
  0 siblings, 0 replies; 60+ messages in thread
From: Finn Thain @ 2016-03-23 10:10 UTC (permalink / raw)
  To: James E.J. Bottomley, Martin K. Petersen, Michael Schmitz,
	linux-m68k, linux-scsi, linux-kernel
  Cc: Ondrej Zary, Sam Creasey

[-- Attachment #1: sun3_scsi-adopt-NCR5380-c --]
[-- Type: text/plain, Size: 8544 bytes --]

Add support for the custom Sun 3 DMA logic to the NCR5380.c core driver.
This code is copied from atari_NCR5380.c.

Signed-off-by: Finn Thain <fthain@telegraphics.com.au>
Reviewed-by: Hannes Reinecke <hare@suse.com>
Tested-by: Michael Schmitz <schmitzmic@gmail.com>
Tested-by: Ondrej Zary <linux@rainbow-software.org>

---

The Sun 3 DMA code is still configured by macros. I have simplified things
slightly but I have avoided more ambitious refactoring. It's not clear to
me what that should look like and I can't test sun3_scsi anyway. At least
this permits the removal of atari_NCR5380.c.

---
 drivers/scsi/NCR5380.c   |  131 +++++++++++++++++++++++++++++++++++++++++++----
 drivers/scsi/sun3_scsi.c |    8 +-
 2 files changed, 124 insertions(+), 15 deletions(-)

Index: linux/drivers/scsi/sun3_scsi.c
===================================================================
--- linux.orig/drivers/scsi/sun3_scsi.c	2016-03-23 21:09:24.000000000 +1100
+++ linux/drivers/scsi/sun3_scsi.c	2016-03-23 21:09:52.000000000 +1100
@@ -54,10 +54,8 @@
 #define NCR5380_abort                   sun3scsi_abort
 #define NCR5380_info                    sun3scsi_info
 
-#define NCR5380_dma_read_setup(instance, data, count) \
-        sun3scsi_dma_setup(instance, data, count, 0)
-#define NCR5380_dma_write_setup(instance, data, count) \
-        sun3scsi_dma_setup(instance, data, count, 1)
+#define NCR5380_dma_recv_setup(instance, data, count) (count)
+#define NCR5380_dma_send_setup(instance, data, count) (count)
 #define NCR5380_dma_residual(instance) \
         sun3scsi_dma_residual(instance)
 #define NCR5380_dma_xfer_len(instance, cmd, phase) \
@@ -406,7 +404,7 @@ static int sun3scsi_dma_finish(int write
 
 }
 	
-#include "atari_NCR5380.c"
+#include "NCR5380.c"
 
 #ifdef SUN3_SCSI_VME
 #define SUN3_SCSI_NAME          "Sun3 NCR5380 VME SCSI"
Index: linux/drivers/scsi/NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/NCR5380.c	2016-03-23 21:09:51.000000000 +1100
+++ linux/drivers/scsi/NCR5380.c	2016-03-23 21:09:52.000000000 +1100
@@ -31,6 +31,8 @@
 
 /* Ported to Atari by Roman Hodek and others. */
 
+/* Adapted for the Sun 3 by Sam Creasey. */
+
 /*
  * Further development / testing that should be done :
  *
@@ -858,6 +860,23 @@ static void NCR5380_dma_complete(struct
 		}
 	}
 
+#ifdef CONFIG_SUN3
+	if ((sun3scsi_dma_finish(rq_data_dir(hostdata->connected->request)))) {
+		pr_err("scsi%d: overrun in UDC counter -- not prepared to deal with this!\n",
+		       instance->host_no);
+		BUG();
+	}
+
+	if ((NCR5380_read(BUS_AND_STATUS_REG) & (BASR_PHASE_MATCH | BASR_ACK)) ==
+	    (BASR_PHASE_MATCH | BASR_ACK)) {
+		pr_err("scsi%d: BASR %02x\n", instance->host_no,
+		       NCR5380_read(BUS_AND_STATUS_REG));
+		pr_err("scsi%d: bus stuck in data phase -- probably a single byte overrun!\n",
+		       instance->host_no);
+		BUG();
+	}
+#endif
+
 	NCR5380_write(MODE_REG, MR_BASE);
 	NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
 	NCR5380_read(RESET_PARITY_INTERRUPT_REG);
@@ -981,10 +1000,16 @@ static irqreturn_t NCR5380_intr(int irq,
 			NCR5380_read(RESET_PARITY_INTERRUPT_REG);
 
 			dsprintk(NDEBUG_INTR, instance, "unknown interrupt\n");
+#ifdef SUN3_SCSI_VME
+			dregs->csr |= CSR_DMA_ENABLE;
+#endif
 		}
 		handled = 1;
 	} else {
 		shost_printk(KERN_NOTICE, instance, "interrupt without IRQ bit\n");
+#ifdef SUN3_SCSI_VME
+		dregs->csr |= CSR_DMA_ENABLE;
+#endif
 	}
 
 	spin_unlock_irqrestore(&hostdata->lock, flags);
@@ -1274,6 +1299,10 @@ static struct scsi_cmnd *NCR5380_select(
 	hostdata->connected = cmd;
 	hostdata->busy[cmd->device->id] |= 1 << cmd->device->lun;
 
+#ifdef SUN3_SCSI_VME
+	dregs->csr |= CSR_INTR;
+#endif
+
 	initialize_SCp(cmd);
 
 	cmd = NULL;
@@ -1557,6 +1586,11 @@ static int NCR5380_transfer_dma(struct S
 	dsprintk(NDEBUG_DMA, instance, "initializing DMA %s: length %d, address %p\n",
 	         (p & SR_IO) ? "receive" : "send", c, d);
 
+#ifdef CONFIG_SUN3
+	/* send start chain */
+	sun3scsi_dma_start(c, *data);
+#endif
+
 	NCR5380_write(TARGET_COMMAND_REG, PHASE_SR_TO_TCR(p));
 	NCR5380_write(MODE_REG, MR_BASE | MR_DMA_MODE | MR_MONITOR_BSY |
 	                        MR_ENABLE_EOP_INTR);
@@ -1577,6 +1611,7 @@ static int NCR5380_transfer_dma(struct S
 	 */
 
 	if (p & SR_IO) {
+		NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
 		NCR5380_io_delay(1);
 		NCR5380_write(START_DMA_INITIATOR_RECEIVE_REG, 0);
 	} else {
@@ -1587,6 +1622,13 @@ static int NCR5380_transfer_dma(struct S
 		NCR5380_io_delay(1);
 	}
 
+#ifdef CONFIG_SUN3
+#ifdef SUN3_SCSI_VME
+	dregs->csr |= CSR_DMA_ENABLE;
+#endif
+	sun3_dma_active = 1;
+#endif
+
 	if (hostdata->flags & FLAG_LATE_DMA_SETUP) {
 		/* On the Falcon, the DMA setup must be done after the last
 		 * NCR access, else the DMA setup gets trashed!
@@ -1718,6 +1760,10 @@ static void NCR5380_information_transfer
 	unsigned char phase, tmp, extended_msg[10], old_phase = 0xff;
 	struct scsi_cmnd *cmd;
 
+#ifdef SUN3_SCSI_VME
+	dregs->csr |= CSR_INTR;
+#endif
+
 	while ((cmd = hostdata->connected)) {
 		struct NCR5380_cmd *ncmd = scsi_cmd_priv(cmd);
 
@@ -1729,6 +1775,31 @@ static void NCR5380_information_transfer
 				old_phase = phase;
 				NCR5380_dprint_phase(NDEBUG_INFORMATION, instance);
 			}
+#ifdef CONFIG_SUN3
+			if (phase == PHASE_CMDOUT) {
+				void *d;
+				unsigned long count;
+
+				if (!cmd->SCp.this_residual && cmd->SCp.buffers_residual) {
+					count = cmd->SCp.buffer->length;
+					d = sg_virt(cmd->SCp.buffer);
+				} else {
+					count = cmd->SCp.this_residual;
+					d = cmd->SCp.ptr;
+				}
+
+				if (sun3_dma_setup_done != cmd &&
+				    sun3scsi_dma_xfer_len(count, cmd) > 0) {
+					sun3scsi_dma_setup(instance, d, count,
+					                   rq_data_dir(cmd->request));
+					sun3_dma_setup_done = cmd;
+				}
+#ifdef SUN3_SCSI_VME
+				dregs->csr |= CSR_INTR;
+#endif
+			}
+#endif /* CONFIG_SUN3 */
+
 			if (sink && (phase != PHASE_MSGOUT)) {
 				NCR5380_write(TARGET_COMMAND_REG, PHASE_SR_TO_TCR(tmp));
 
@@ -1811,6 +1882,10 @@ static void NCR5380_information_transfer
 					                     (unsigned char **)&cmd->SCp.ptr);
 					cmd->SCp.this_residual -= transfersize - len;
 				}
+#ifdef CONFIG_SUN3
+				if (sun3_dma_setup_done == cmd)
+					sun3_dma_setup_done = NULL;
+#endif
 				return;
 			case PHASE_MSGIN:
 				len = 1;
@@ -1889,6 +1964,9 @@ static void NCR5380_information_transfer
 
 					/* Enable reselect interrupts */
 					NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
+#ifdef SUN3_SCSI_VME
+					dregs->csr |= CSR_DMA_ENABLE;
+#endif
 					return;
 					/*
 					 * The SCSI data pointer is *IMPLICITLY* saved on a disconnect
@@ -2040,10 +2118,8 @@ static void NCR5380_reselect(struct Scsi
 {
 	struct NCR5380_hostdata *hostdata = shost_priv(instance);
 	unsigned char target_mask;
-	unsigned char lun, phase;
-	int len;
+	unsigned char lun;
 	unsigned char msg[3];
-	unsigned char *data;
 	struct NCR5380_cmd *ncmd;
 	struct scsi_cmnd *tmp;
 
@@ -2085,15 +2161,26 @@ static void NCR5380_reselect(struct Scsi
 		return;
 	}
 
-	len = 1;
-	data = msg;
-	phase = PHASE_MSGIN;
-	NCR5380_transfer_pio(instance, &phase, &len, &data);
+#ifdef CONFIG_SUN3
+	/* acknowledge toggle to MSGIN */
+	NCR5380_write(TARGET_COMMAND_REG, PHASE_SR_TO_TCR(PHASE_MSGIN));
+
+	/* peek at the byte without really hitting the bus */
+	msg[0] = NCR5380_read(CURRENT_SCSI_DATA_REG);
+#else
+	{
+		int len = 1;
+		unsigned char *data = msg;
+		unsigned char phase = PHASE_MSGIN;
 
-	if (len) {
-		do_abort(instance);
-		return;
+		NCR5380_transfer_pio(instance, &phase, &len, &data);
+
+		if (len) {
+			do_abort(instance);
+			return;
+		}
 	}
+#endif /* CONFIG_SUN3 */
 
 	if (!(msg[0] & 0x80)) {
 		shost_printk(KERN_ERR, instance, "expecting IDENTIFY message, got ");
@@ -2141,6 +2228,30 @@ static void NCR5380_reselect(struct Scsi
 		return;
 	}
 
+#ifdef CONFIG_SUN3
+	{
+		void *d;
+		unsigned long count;
+
+		if (!tmp->SCp.this_residual && tmp->SCp.buffers_residual) {
+			count = tmp->SCp.buffer->length;
+			d = sg_virt(tmp->SCp.buffer);
+		} else {
+			count = tmp->SCp.this_residual;
+			d = tmp->SCp.ptr;
+		}
+
+		if (sun3_dma_setup_done != tmp &&
+		    sun3scsi_dma_xfer_len(count, tmp) > 0) {
+			sun3scsi_dma_setup(instance, d, count,
+			                   rq_data_dir(tmp->request));
+			sun3_dma_setup_done = tmp;
+		}
+	}
+
+	NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_ACK);
+#endif /* CONFIG_SUN3 */
+
 	/* Accept message by clearing ACK */
 	NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
 

^ permalink raw reply	[flat|nested] 60+ messages in thread

* [PATCH v4 13/23] ncr5380: Remove disused atari_NCR5380.c core driver
  2016-03-23 10:10 ` Finn Thain
@ 2016-03-23 10:10   ` Finn Thain
  -1 siblings, 0 replies; 60+ messages in thread
From: Finn Thain @ 2016-03-23 10:10 UTC (permalink / raw)
  To: James E.J. Bottomley, Martin K. Petersen, Michael Schmitz,
	linux-m68k, linux-scsi, linux-kernel
  Cc: Ondrej Zary, Sam Creasey

[-- Attachment #1: ncr5380-remove-disused-code --]
[-- Type: text/plain, Size: 91584 bytes --]

Now that atari_scsi and sun3_scsi have been converted to use the NCR5380.c
core driver, remove atari_NCR5380.c. Also remove the last vestiges of its
Tagged Command Queueing implementation from the wrapper drivers.

The TCQ support in atari_NCR5380.c is abandoned by this patch. It is not
merged into the remaining core driver because,

1) atari_scsi defines SUPPORT_TAGS but leaves FLAG_TAGGED_QUEUING disabled
by default, which indicates that it is mostly undesirable.

2) I'm told that it doesn't work correctly when enabled.

3) The algorithm does not make use of block layer tags which it will have
to do because scmd->tag is deprecated.

4) sun3_scsi doesn't define SUPPORT_TAGS at all, yet the the SUPPORT_TAGS
macro interacts with the CONFIG_SUN3 macro in 'interesting' ways.

5) Compile-time configuration with macros like SUPPORT_TAGS caused the
configuration space to explode, leading to untestable and unmaintainable
code that is too hard to reason about.

The merge_contiguous_buffers() code is also abandoned. This was unused
by sun3_scsi. Only atari_scsi used it and then only on TT, because only TT
supports scatter/gather. I suspect that the TT would work fine with
ENABLE_CLUSTERING instead. If someone can benchmark the difference then
perhaps the merge_contiguous_buffers() code can be be justified. Until
then we are better off without the extra complexity.

Signed-off-by: Finn Thain <fthain@telegraphics.com.au>
Reviewed-by: Hannes Reinecke <hare@suse.com>
Tested-by: Michael Schmitz <schmitzmic@gmail.com>
Tested-by: Ondrej Zary <linux@rainbow-software.org>

---
 drivers/scsi/NCR5380.c       |   22 
 drivers/scsi/NCR5380.h       |   19 
 drivers/scsi/atari_NCR5380.c | 2632 -------------------------------------------
 drivers/scsi/atari_scsi.c    |   11 
 drivers/scsi/mac_scsi.c      |    8 
 drivers/scsi/sun3_scsi.c     |   11 
 6 files changed, 4 insertions(+), 2699 deletions(-)

Index: linux/drivers/scsi/atari_scsi.c
===================================================================
--- linux.orig/drivers/scsi/atari_scsi.c	2016-03-23 21:09:51.000000000 +1100
+++ linux/drivers/scsi/atari_scsi.c	2016-03-23 21:09:53.000000000 +1100
@@ -87,9 +87,6 @@
 
 /* Definitions for the core NCR5380 driver. */
 
-#define SUPPORT_TAGS
-#define MAX_TAGS                        32
-
 #define NCR5380_implementation_fields   /* none */
 
 #define NCR5380_read(reg)               atari_scsi_reg_read(reg)
@@ -189,8 +186,6 @@ static int setup_cmd_per_lun = -1;
 module_param(setup_cmd_per_lun, int, 0);
 static int setup_sg_tablesize = -1;
 module_param(setup_sg_tablesize, int, 0);
-static int setup_use_tagged_queuing = -1;
-module_param(setup_use_tagged_queuing, int, 0);
 static int setup_hostid = -1;
 module_param(setup_hostid, int, 0);
 static int setup_toshiba_delay = -1;
@@ -479,8 +474,7 @@ static int __init atari_scsi_setup(char
 		setup_sg_tablesize = ints[3];
 	if (ints[0] >= 4)
 		setup_hostid = ints[4];
-	if (ints[0] >= 5)
-		setup_use_tagged_queuing = ints[5];
+	/* ints[5] (use_tagged_queuing) is ignored */
 	/* ints[6] (use_pdma) is ignored */
 	if (ints[0] >= 7)
 		setup_toshiba_delay = ints[7];
@@ -853,9 +847,6 @@ static int __init atari_scsi_probe(struc
 	instance->irq = irq->start;
 
 	host_flags |= IS_A_TT() ? 0 : FLAG_LATE_DMA_SETUP;
-#ifdef SUPPORT_TAGS
-	host_flags |= setup_use_tagged_queuing > 0 ? FLAG_TAGGED_QUEUING : 0;
-#endif
 	host_flags |= setup_toshiba_delay > 0 ? FLAG_TOSHIBA_DELAY : 0;
 
 	error = NCR5380_init(instance, host_flags);
Index: linux/drivers/scsi/sun3_scsi.c
===================================================================
--- linux.orig/drivers/scsi/sun3_scsi.c	2016-03-23 21:09:52.000000000 +1100
+++ linux/drivers/scsi/sun3_scsi.c	2016-03-23 21:09:53.000000000 +1100
@@ -41,9 +41,6 @@
 
 /* Definitions for the core NCR5380 driver. */
 
-/* #define SUPPORT_TAGS */
-/* #define MAX_TAGS                     32 */
-
 #define NCR5380_implementation_fields   /* none */
 
 #define NCR5380_read(reg)               sun3scsi_read(reg)
@@ -75,10 +72,6 @@ static int setup_cmd_per_lun = -1;
 module_param(setup_cmd_per_lun, int, 0);
 static int setup_sg_tablesize = -1;
 module_param(setup_sg_tablesize, int, 0);
-#ifdef SUPPORT_TAGS
-static int setup_use_tagged_queuing = -1;
-module_param(setup_use_tagged_queuing, int, 0);
-#endif
 static int setup_hostid = -1;
 module_param(setup_hostid, int, 0);
 
@@ -512,10 +505,6 @@ static int __init sun3_scsi_probe(struct
 	instance->io_port = (unsigned long)ioaddr;
 	instance->irq = irq->start;
 
-#ifdef SUPPORT_TAGS
-	host_flags |= setup_use_tagged_queuing > 0 ? FLAG_TAGGED_QUEUING : 0;
-#endif
-
 	error = NCR5380_init(instance, host_flags);
 	if (error)
 		goto fail_init;
Index: linux/drivers/scsi/mac_scsi.c
===================================================================
--- linux.orig/drivers/scsi/mac_scsi.c	2016-03-23 21:09:47.000000000 +1100
+++ linux/drivers/scsi/mac_scsi.c	2016-03-23 21:09:53.000000000 +1100
@@ -55,8 +55,6 @@ static int setup_sg_tablesize = -1;
 module_param(setup_sg_tablesize, int, 0);
 static int setup_use_pdma = -1;
 module_param(setup_use_pdma, int, 0);
-static int setup_use_tagged_queuing = -1;
-module_param(setup_use_tagged_queuing, int, 0);
 static int setup_hostid = -1;
 module_param(setup_hostid, int, 0);
 static int setup_toshiba_delay = -1;
@@ -95,8 +93,7 @@ static int __init mac_scsi_setup(char *s
 		setup_sg_tablesize = ints[3];
 	if (ints[0] >= 4)
 		setup_hostid = ints[4];
-	if (ints[0] >= 5)
-		setup_use_tagged_queuing = ints[5];
+	/* ints[5] (use_tagged_queuing) is ignored */
 	if (ints[0] >= 6)
 		setup_use_pdma = ints[6];
 	if (ints[0] >= 7)
@@ -382,9 +379,6 @@ static int __init mac_scsi_probe(struct
 	} else
 		host_flags |= FLAG_NO_PSEUDO_DMA;
 
-#ifdef SUPPORT_TAGS
-	host_flags |= setup_use_tagged_queuing > 0 ? FLAG_TAGGED_QUEUING : 0;
-#endif
 	host_flags |= setup_toshiba_delay > 0 ? FLAG_TOSHIBA_DELAY : 0;
 
 	error = NCR5380_init(instance, host_flags | FLAG_LATE_DMA_SETUP);
Index: linux/drivers/scsi/NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/NCR5380.c	2016-03-23 21:09:52.000000000 +1100
+++ linux/drivers/scsi/NCR5380.c	2016-03-23 21:09:53.000000000 +1100
@@ -34,13 +34,6 @@
 /* Adapted for the Sun 3 by Sam Creasey. */
 
 /*
- * Further development / testing that should be done :
- *
- * 4.  Test SCSI-II tagged queueing (I have no devices which support
- * tagged queueing)
- */
-
-/*
  * Design
  *
  * This is a generic 5380 driver.  To use it on a different platform,
@@ -1257,14 +1250,6 @@ static struct scsi_cmnd *NCR5380_select(
 	 * was true but before BSY was false during selection, the information
 	 * transfer phase should be a MESSAGE OUT phase so that we can send the
 	 * IDENTIFY message.
-	 *
-	 * If SCSI-II tagged queuing is enabled, we also send a SIMPLE_QUEUE_TAG
-	 * message (2 bytes) with a tag ID that we increment with every command
-	 * until it wraps back to 0.
-	 *
-	 * XXX - it turns out that there are some broken SCSI-II devices,
-	 * which claim to support tagged queuing but fail when more than
-	 * some number of commands are issued at once.
 	 */
 
 	/* Wait for start of REQ/ACK handshake */
@@ -1287,9 +1272,6 @@ static struct scsi_cmnd *NCR5380_select(
 	tmp[0] = IDENTIFY(((instance->irq == NO_IRQ) ? 0 : 1), cmd->device->lun);
 
 	len = 1;
-	cmd->tag = 0;
-
-	/* Send message(s) */
 	data = tmp;
 	phase = PHASE_MSGOUT;
 	NCR5380_transfer_pio(instance, &phase, &len, &data);
@@ -2256,8 +2238,8 @@ static void NCR5380_reselect(struct Scsi
 	NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
 
 	hostdata->connected = tmp;
-	dsprintk(NDEBUG_RESELECTION, instance, "nexus established, target %d, lun %llu, tag %d\n",
-	         scmd_id(tmp), tmp->device->lun, tmp->tag);
+	dsprintk(NDEBUG_RESELECTION, instance, "nexus established, target %d, lun %llu\n",
+	         scmd_id(tmp), tmp->device->lun);
 }
 
 /**
Index: linux/drivers/scsi/NCR5380.h
===================================================================
--- linux.orig/drivers/scsi/NCR5380.h	2016-03-23 21:09:28.000000000 +1100
+++ linux/drivers/scsi/NCR5380.h	2016-03-23 21:09:53.000000000 +1100
@@ -199,13 +199,6 @@
 
 #define PHASE_SR_TO_TCR(phase) ((phase) >> 2)
 
-/* 
- * "Special" value for the (unsigned char) command tag, to indicate
- * I_T_L nexus instead of I_T_L_Q.
- */
-
-#define TAG_NONE	0xff
-
 /*
  * These are "special" values for the irq and dma_channel fields of the 
  * Scsi_Host structure
@@ -223,17 +216,8 @@
 #define FLAG_DMA_FIXUP			1	/* Use DMA errata workarounds */
 #define FLAG_NO_PSEUDO_DMA		8	/* Inhibit DMA */
 #define FLAG_LATE_DMA_SETUP		32	/* Setup NCR before DMA H/W */
-#define FLAG_TAGGED_QUEUING		64	/* as X3T9.2 spelled it */
 #define FLAG_TOSHIBA_DELAY		128	/* Allow for borken CD-ROMs */
 
-#ifdef SUPPORT_TAGS
-struct tag_alloc {
-	DECLARE_BITMAP(allocated, MAX_TAGS);
-	int nr_allocated;
-	int queue_size;
-};
-#endif
-
 struct NCR5380_hostdata {
 	NCR5380_implementation_fields;		/* implementation specific */
 	struct Scsi_Host *host;			/* Host backpointer */
@@ -254,9 +238,6 @@ struct NCR5380_hostdata {
 	int read_overruns;                /* number of bytes to cut from a
 	                                   * transfer to handle chip overruns */
 	struct work_struct main_task;
-#ifdef SUPPORT_TAGS
-	struct tag_alloc TagAlloc[8][8];	/* 8 targets and 8 LUNs */
-#endif
 	struct workqueue_struct *work_q;
 	unsigned long accesses_per_ms;	/* chip register accesses per ms */
 };
Index: linux/drivers/scsi/atari_NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/atari_NCR5380.c	2016-03-23 21:09:24.000000000 +1100
+++ /dev/null	1970-01-01 00:00:00.000000000 +0000
@@ -1,2632 +0,0 @@
-/*
- * NCR 5380 generic driver routines.  These should make it *trivial*
- * to implement 5380 SCSI drivers under Linux with a non-trantor
- * architecture.
- *
- * Note that these routines also work with NR53c400 family chips.
- *
- * Copyright 1993, Drew Eckhardt
- * Visionary Computing
- * (Unix and Linux consulting and custom programming)
- * drew@colorado.edu
- * +1 (303) 666-5836
- *
- * For more information, please consult
- *
- * NCR 5380 Family
- * SCSI Protocol Controller
- * Databook
- *
- * NCR Microelectronics
- * 1635 Aeroplaza Drive
- * Colorado Springs, CO 80916
- * 1+ (719) 578-3400
- * 1+ (800) 334-5454
- */
-
-/* Ported to Atari by Roman Hodek and others. */
-
-/* Adapted for the sun3 by Sam Creasey. */
-
-/*
- * Design
- *
- * This is a generic 5380 driver.  To use it on a different platform,
- * one simply writes appropriate system specific macros (ie, data
- * transfer - some PC's will use the I/O bus, 68K's must use
- * memory mapped) and drops this file in their 'C' wrapper.
- *
- * As far as command queueing, two queues are maintained for
- * each 5380 in the system - commands that haven't been issued yet,
- * and commands that are currently executing.  This means that an
- * unlimited number of commands may be queued, letting
- * more commands propagate from the higher driver levels giving higher
- * throughput.  Note that both I_T_L and I_T_L_Q nexuses are supported,
- * allowing multiple commands to propagate all the way to a SCSI-II device
- * while a command is already executing.
- *
- *
- * Issues specific to the NCR5380 :
- *
- * When used in a PIO or pseudo-dma mode, the NCR5380 is a braindead
- * piece of hardware that requires you to sit in a loop polling for
- * the REQ signal as long as you are connected.  Some devices are
- * brain dead (ie, many TEXEL CD ROM drives) and won't disconnect
- * while doing long seek operations. [...] These
- * broken devices are the exception rather than the rule and I'd rather
- * spend my time optimizing for the normal case.
- *
- * Architecture :
- *
- * At the heart of the design is a coroutine, NCR5380_main,
- * which is started from a workqueue for each NCR5380 host in the
- * system.  It attempts to establish I_T_L or I_T_L_Q nexuses by
- * removing the commands from the issue queue and calling
- * NCR5380_select() if a nexus is not established.
- *
- * Once a nexus is established, the NCR5380_information_transfer()
- * phase goes through the various phases as instructed by the target.
- * if the target goes into MSG IN and sends a DISCONNECT message,
- * the command structure is placed into the per instance disconnected
- * queue, and NCR5380_main tries to find more work.  If the target is
- * idle for too long, the system will try to sleep.
- *
- * If a command has disconnected, eventually an interrupt will trigger,
- * calling NCR5380_intr()  which will in turn call NCR5380_reselect
- * to reestablish a nexus.  This will run main if necessary.
- *
- * On command termination, the done function will be called as
- * appropriate.
- *
- * SCSI pointers are maintained in the SCp field of SCSI command
- * structures, being initialized after the command is connected
- * in NCR5380_select, and set as appropriate in NCR5380_information_transfer.
- * Note that in violation of the standard, an implicit SAVE POINTERS operation
- * is done, since some BROKEN disks fail to issue an explicit SAVE POINTERS.
- */
-
-/*
- * Using this file :
- * This file a skeleton Linux SCSI driver for the NCR 5380 series
- * of chips.  To use it, you write an architecture specific functions
- * and macros and include this file in your driver.
- *
- * These macros control options :
- * AUTOSENSE - if defined, REQUEST SENSE will be performed automatically
- * for commands that return with a CHECK CONDITION status.
- *
- * DIFFERENTIAL - if defined, NCR53c81 chips will use external differential
- * transceivers.
- *
- * REAL_DMA - if defined, REAL DMA is used during the data transfer phases.
- *
- * SUPPORT_TAGS - if defined, SCSI-2 tagged queuing is used where possible
- *
- * These macros MUST be defined :
- *
- * NCR5380_read(register)  - read from the specified register
- *
- * NCR5380_write(register, value) - write to the specific register
- *
- * NCR5380_implementation_fields  - additional fields needed for this
- * specific implementation of the NCR5380
- *
- * Either real DMA *or* pseudo DMA may be implemented
- * Note that the DMA setup functions should return the number of bytes
- * that they were able to program the controller for.
- *
- * NCR5380_dma_write_setup(instance, src, count) - initialize
- * NCR5380_dma_read_setup(instance, dst, count) - initialize
- * NCR5380_dma_residual(instance); - residual count
- *
- * PSEUDO functions :
- * NCR5380_pwrite(instance, src, count)
- * NCR5380_pread(instance, dst, count);
- *
- * The generic driver is initialized by calling NCR5380_init(instance),
- * after setting the appropriate host specific fields and ID.  If the
- * driver wishes to autoprobe for an IRQ line, the NCR5380_probe_irq(instance,
- * possible) function may be used.
- */
-
-static int do_abort(struct Scsi_Host *);
-static void do_reset(struct Scsi_Host *);
-
-#ifdef SUPPORT_TAGS
-
-/*
- * Functions for handling tagged queuing
- * =====================================
- *
- * ++roman (01/96): Now I've implemented SCSI-2 tagged queuing. Some notes:
- *
- * Using consecutive numbers for the tags is no good idea in my eyes. There
- * could be wrong re-usings if the counter (8 bit!) wraps and some early
- * command has been preempted for a long time. My solution: a bitfield for
- * remembering used tags.
- *
- * There's also the problem that each target has a certain queue size, but we
- * cannot know it in advance :-( We just see a QUEUE_FULL status being
- * returned. So, in this case, the driver internal queue size assumption is
- * reduced to the number of active tags if QUEUE_FULL is returned by the
- * target.
- *
- * We're also not allowed running tagged commands as long as an untagged
- * command is active. And REQUEST SENSE commands after a contingent allegiance
- * condition _must_ be untagged. To keep track whether an untagged command has
- * been issued, the host->busy array is still employed, as it is without
- * support for tagged queuing.
- *
- * One could suspect that there are possible race conditions between
- * is_lun_busy(), cmd_get_tag() and cmd_free_tag(). But I think this isn't the
- * case: is_lun_busy() and cmd_get_tag() are both called from NCR5380_main(),
- * which already guaranteed to be running at most once. It is also the only
- * place where tags/LUNs are allocated. So no other allocation can slip
- * between that pair, there could only happen a reselection, which can free a
- * tag, but that doesn't hurt. Only the sequence in cmd_free_tag() becomes
- * important: the tag bit must be cleared before 'nr_allocated' is decreased.
- */
-
-static void __init init_tags(struct NCR5380_hostdata *hostdata)
-{
-	int target, lun;
-	struct tag_alloc *ta;
-
-	if (!(hostdata->flags & FLAG_TAGGED_QUEUING))
-		return;
-
-	for (target = 0; target < 8; ++target) {
-		for (lun = 0; lun < 8; ++lun) {
-			ta = &hostdata->TagAlloc[target][lun];
-			bitmap_zero(ta->allocated, MAX_TAGS);
-			ta->nr_allocated = 0;
-			/* At the beginning, assume the maximum queue size we could
-			 * support (MAX_TAGS). This value will be decreased if the target
-			 * returns QUEUE_FULL status.
-			 */
-			ta->queue_size = MAX_TAGS;
-		}
-	}
-}
-
-
-/* Check if we can issue a command to this LUN: First see if the LUN is marked
- * busy by an untagged command. If the command should use tagged queuing, also
- * check that there is a free tag and the target's queue won't overflow. This
- * function should be called with interrupts disabled to avoid race
- * conditions.
- */
-
-static int is_lun_busy(struct scsi_cmnd *cmd, int should_be_tagged)
-{
-	u8 lun = cmd->device->lun;
-	struct Scsi_Host *instance = cmd->device->host;
-	struct NCR5380_hostdata *hostdata = shost_priv(instance);
-
-	if (hostdata->busy[cmd->device->id] & (1 << lun))
-		return 1;
-	if (!should_be_tagged ||
-	    !(hostdata->flags & FLAG_TAGGED_QUEUING) ||
-	    !cmd->device->tagged_supported)
-		return 0;
-	if (hostdata->TagAlloc[scmd_id(cmd)][lun].nr_allocated >=
-	    hostdata->TagAlloc[scmd_id(cmd)][lun].queue_size) {
-		dsprintk(NDEBUG_TAGS, instance, "target %d lun %d: no free tags\n",
-		         scmd_id(cmd), lun);
-		return 1;
-	}
-	return 0;
-}
-
-
-/* Allocate a tag for a command (there are no checks anymore, check_lun_busy()
- * must be called before!), or reserve the LUN in 'busy' if the command is
- * untagged.
- */
-
-static void cmd_get_tag(struct scsi_cmnd *cmd, int should_be_tagged)
-{
-	u8 lun = cmd->device->lun;
-	struct Scsi_Host *instance = cmd->device->host;
-	struct NCR5380_hostdata *hostdata = shost_priv(instance);
-
-	/* If we or the target don't support tagged queuing, allocate the LUN for
-	 * an untagged command.
-	 */
-	if (!should_be_tagged ||
-	    !(hostdata->flags & FLAG_TAGGED_QUEUING) ||
-	    !cmd->device->tagged_supported) {
-		cmd->tag = TAG_NONE;
-		hostdata->busy[cmd->device->id] |= (1 << lun);
-		dsprintk(NDEBUG_TAGS, instance, "target %d lun %d now allocated by untagged command\n",
-		         scmd_id(cmd), lun);
-	} else {
-		struct tag_alloc *ta = &hostdata->TagAlloc[scmd_id(cmd)][lun];
-
-		cmd->tag = find_first_zero_bit(ta->allocated, MAX_TAGS);
-		set_bit(cmd->tag, ta->allocated);
-		ta->nr_allocated++;
-		dsprintk(NDEBUG_TAGS, instance, "using tag %d for target %d lun %d (%d tags allocated)\n",
-		         cmd->tag, scmd_id(cmd), lun, ta->nr_allocated);
-	}
-}
-
-
-/* Mark the tag of command 'cmd' as free, or in case of an untagged command,
- * unlock the LUN.
- */
-
-static void cmd_free_tag(struct scsi_cmnd *cmd)
-{
-	u8 lun = cmd->device->lun;
-	struct Scsi_Host *instance = cmd->device->host;
-	struct NCR5380_hostdata *hostdata = shost_priv(instance);
-
-	if (cmd->tag == TAG_NONE) {
-		hostdata->busy[cmd->device->id] &= ~(1 << lun);
-		dsprintk(NDEBUG_TAGS, instance, "target %d lun %d untagged cmd freed\n",
-		         scmd_id(cmd), lun);
-	} else if (cmd->tag >= MAX_TAGS) {
-		shost_printk(KERN_NOTICE, instance,
-		             "trying to free bad tag %d!\n", cmd->tag);
-	} else {
-		struct tag_alloc *ta = &hostdata->TagAlloc[scmd_id(cmd)][lun];
-		clear_bit(cmd->tag, ta->allocated);
-		ta->nr_allocated--;
-		dsprintk(NDEBUG_TAGS, instance, "freed tag %d for target %d lun %d\n",
-		         cmd->tag, scmd_id(cmd), lun);
-	}
-}
-
-
-static void free_all_tags(struct NCR5380_hostdata *hostdata)
-{
-	int target, lun;
-	struct tag_alloc *ta;
-
-	if (!(hostdata->flags & FLAG_TAGGED_QUEUING))
-		return;
-
-	for (target = 0; target < 8; ++target) {
-		for (lun = 0; lun < 8; ++lun) {
-			ta = &hostdata->TagAlloc[target][lun];
-			bitmap_zero(ta->allocated, MAX_TAGS);
-			ta->nr_allocated = 0;
-		}
-	}
-}
-
-#endif /* SUPPORT_TAGS */
-
-/**
- * merge_contiguous_buffers - coalesce scatter-gather list entries
- * @cmd: command requesting IO
- *
- * Try to merge several scatter-gather buffers into one DMA transfer.
- * This is possible if the scatter buffers lie on physically
- * contiguous addresses. The first scatter-gather buffer's data are
- * assumed to be already transferred into cmd->SCp.this_residual.
- * Every buffer merged avoids an interrupt and a DMA setup operation.
- */
-
-static void merge_contiguous_buffers(struct scsi_cmnd *cmd)
-{
-#if !defined(CONFIG_SUN3)
-	unsigned long endaddr;
-#if (NDEBUG & NDEBUG_MERGING)
-	unsigned long oldlen = cmd->SCp.this_residual;
-	int cnt = 1;
-#endif
-
-	for (endaddr = virt_to_phys(cmd->SCp.ptr + cmd->SCp.this_residual - 1) + 1;
-	     cmd->SCp.buffers_residual &&
-	     virt_to_phys(sg_virt(&cmd->SCp.buffer[1])) == endaddr;) {
-		dprintk(NDEBUG_MERGING, "VTOP(%p) == %08lx -> merging\n",
-			   page_address(sg_page(&cmd->SCp.buffer[1])), endaddr);
-#if (NDEBUG & NDEBUG_MERGING)
-		++cnt;
-#endif
-		++cmd->SCp.buffer;
-		--cmd->SCp.buffers_residual;
-		cmd->SCp.this_residual += cmd->SCp.buffer->length;
-		endaddr += cmd->SCp.buffer->length;
-	}
-#if (NDEBUG & NDEBUG_MERGING)
-	if (oldlen != cmd->SCp.this_residual)
-		dprintk(NDEBUG_MERGING, "merged %d buffers from %p, new length %08x\n",
-			   cnt, cmd->SCp.ptr, cmd->SCp.this_residual);
-#endif
-#endif /* !defined(CONFIG_SUN3) */
-}
-
-/**
- * initialize_SCp - init the scsi pointer field
- * @cmd: command block to set up
- *
- * Set up the internal fields in the SCSI command.
- */
-
-static inline void initialize_SCp(struct scsi_cmnd *cmd)
-{
-	/*
-	 * Initialize the Scsi Pointer field so that all of the commands in the
-	 * various queues are valid.
-	 */
-
-	if (scsi_bufflen(cmd)) {
-		cmd->SCp.buffer = scsi_sglist(cmd);
-		cmd->SCp.buffers_residual = scsi_sg_count(cmd) - 1;
-		cmd->SCp.ptr = sg_virt(cmd->SCp.buffer);
-		cmd->SCp.this_residual = cmd->SCp.buffer->length;
-
-		merge_contiguous_buffers(cmd);
-	} else {
-		cmd->SCp.buffer = NULL;
-		cmd->SCp.buffers_residual = 0;
-		cmd->SCp.ptr = NULL;
-		cmd->SCp.this_residual = 0;
-	}
-
-	cmd->SCp.Status = 0;
-	cmd->SCp.Message = 0;
-}
-
-/**
- * NCR5380_poll_politely2 - wait for two chip register values
- * @instance: controller to poll
- * @reg1: 5380 register to poll
- * @bit1: Bitmask to check
- * @val1: Expected value
- * @reg2: Second 5380 register to poll
- * @bit2: Second bitmask to check
- * @val2: Second expected value
- * @wait: Time-out in jiffies
- *
- * Polls the chip in a reasonably efficient manner waiting for an
- * event to occur. After a short quick poll we begin to yield the CPU
- * (if possible). In irq contexts the time-out is arbitrarily limited.
- * Callers may hold locks as long as they are held in irq mode.
- *
- * Returns 0 if either or both event(s) occurred otherwise -ETIMEDOUT.
- */
-
-static int NCR5380_poll_politely2(struct Scsi_Host *instance,
-                                  int reg1, int bit1, int val1,
-                                  int reg2, int bit2, int val2, int wait)
-{
-	struct NCR5380_hostdata *hostdata = shost_priv(instance);
-	unsigned long deadline = jiffies + wait;
-	unsigned long n;
-
-	/* Busy-wait for up to 10 ms */
-	n = min(10000U, jiffies_to_usecs(wait));
-	n *= hostdata->accesses_per_ms;
-	n /= 2000;
-	do {
-		if ((NCR5380_read(reg1) & bit1) == val1)
-			return 0;
-		if ((NCR5380_read(reg2) & bit2) == val2)
-			return 0;
-		cpu_relax();
-	} while (n--);
-
-	if (irqs_disabled() || in_interrupt())
-		return -ETIMEDOUT;
-
-	/* Repeatedly sleep for 1 ms until deadline */
-	while (time_is_after_jiffies(deadline)) {
-		schedule_timeout_uninterruptible(1);
-		if ((NCR5380_read(reg1) & bit1) == val1)
-			return 0;
-		if ((NCR5380_read(reg2) & bit2) == val2)
-			return 0;
-	}
-
-	return -ETIMEDOUT;
-}
-
-static inline int NCR5380_poll_politely(struct Scsi_Host *instance,
-                                        int reg, int bit, int val, int wait)
-{
-	return NCR5380_poll_politely2(instance, reg, bit, val,
-	                                        reg, bit, val, wait);
-}
-
-#if NDEBUG
-static struct {
-	unsigned char mask;
-	const char *name;
-} signals[] = {
-	{SR_DBP, "PARITY"},
-	{SR_RST, "RST"},
-	{SR_BSY, "BSY"},
-	{SR_REQ, "REQ"},
-	{SR_MSG, "MSG"},
-	{SR_CD, "CD"},
-	{SR_IO, "IO"},
-	{SR_SEL, "SEL"},
-	{0, NULL}
-},
-basrs[] = {
-	{BASR_ATN, "ATN"},
-	{BASR_ACK, "ACK"},
-	{0, NULL}
-},
-icrs[] = {
-	{ICR_ASSERT_RST, "ASSERT RST"},
-	{ICR_ASSERT_ACK, "ASSERT ACK"},
-	{ICR_ASSERT_BSY, "ASSERT BSY"},
-	{ICR_ASSERT_SEL, "ASSERT SEL"},
-	{ICR_ASSERT_ATN, "ASSERT ATN"},
-	{ICR_ASSERT_DATA, "ASSERT DATA"},
-	{0, NULL}
-},
-mrs[] = {
-	{MR_BLOCK_DMA_MODE, "MODE BLOCK DMA"},
-	{MR_TARGET, "MODE TARGET"},
-	{MR_ENABLE_PAR_CHECK, "MODE PARITY CHECK"},
-	{MR_ENABLE_PAR_INTR, "MODE PARITY INTR"},
-	{MR_ENABLE_EOP_INTR, "MODE EOP INTR"},
-	{MR_MONITOR_BSY, "MODE MONITOR BSY"},
-	{MR_DMA_MODE, "MODE DMA"},
-	{MR_ARBITRATE, "MODE ARBITRATION"},
-	{0, NULL}
-};
-
-/**
- * NCR5380_print - print scsi bus signals
- * @instance: adapter state to dump
- *
- * Print the SCSI bus signals for debugging purposes
- */
-
-static void NCR5380_print(struct Scsi_Host *instance)
-{
-	unsigned char status, data, basr, mr, icr, i;
-
-	data = NCR5380_read(CURRENT_SCSI_DATA_REG);
-	status = NCR5380_read(STATUS_REG);
-	mr = NCR5380_read(MODE_REG);
-	icr = NCR5380_read(INITIATOR_COMMAND_REG);
-	basr = NCR5380_read(BUS_AND_STATUS_REG);
-
-	printk("STATUS_REG: %02x ", status);
-	for (i = 0; signals[i].mask; ++i)
-		if (status & signals[i].mask)
-			printk(",%s", signals[i].name);
-	printk("\nBASR: %02x ", basr);
-	for (i = 0; basrs[i].mask; ++i)
-		if (basr & basrs[i].mask)
-			printk(",%s", basrs[i].name);
-	printk("\nICR: %02x ", icr);
-	for (i = 0; icrs[i].mask; ++i)
-		if (icr & icrs[i].mask)
-			printk(",%s", icrs[i].name);
-	printk("\nMODE: %02x ", mr);
-	for (i = 0; mrs[i].mask; ++i)
-		if (mr & mrs[i].mask)
-			printk(",%s", mrs[i].name);
-	printk("\n");
-}
-
-static struct {
-	unsigned char value;
-	const char *name;
-} phases[] = {
-	{PHASE_DATAOUT, "DATAOUT"},
-	{PHASE_DATAIN, "DATAIN"},
-	{PHASE_CMDOUT, "CMDOUT"},
-	{PHASE_STATIN, "STATIN"},
-	{PHASE_MSGOUT, "MSGOUT"},
-	{PHASE_MSGIN, "MSGIN"},
-	{PHASE_UNKNOWN, "UNKNOWN"}
-};
-
-/**
- * NCR5380_print_phase - show SCSI phase
- * @instance: adapter to dump
- *
- * Print the current SCSI phase for debugging purposes
- */
-
-static void NCR5380_print_phase(struct Scsi_Host *instance)
-{
-	unsigned char status;
-	int i;
-
-	status = NCR5380_read(STATUS_REG);
-	if (!(status & SR_REQ))
-		shost_printk(KERN_DEBUG, instance, "REQ not asserted, phase unknown.\n");
-	else {
-		for (i = 0; (phases[i].value != PHASE_UNKNOWN) &&
-		     (phases[i].value != (status & PHASE_MASK)); ++i)
-			;
-		shost_printk(KERN_DEBUG, instance, "phase %s\n", phases[i].name);
-	}
-}
-#endif
-
-/**
- * NCR58380_info - report driver and host information
- * @instance: relevant scsi host instance
- *
- * For use as the host template info() handler.
- */
-
-static const char *NCR5380_info(struct Scsi_Host *instance)
-{
-	struct NCR5380_hostdata *hostdata = shost_priv(instance);
-
-	return hostdata->info;
-}
-
-static void prepare_info(struct Scsi_Host *instance)
-{
-	struct NCR5380_hostdata *hostdata = shost_priv(instance);
-
-	snprintf(hostdata->info, sizeof(hostdata->info),
-	         "%s, io_port 0x%lx, n_io_port %d, "
-	         "base 0x%lx, irq %d, "
-	         "can_queue %d, cmd_per_lun %d, "
-	         "sg_tablesize %d, this_id %d, "
-	         "flags { %s%s}, "
-	         "options { %s} ",
-	         instance->hostt->name, instance->io_port, instance->n_io_port,
-	         instance->base, instance->irq,
-	         instance->can_queue, instance->cmd_per_lun,
-	         instance->sg_tablesize, instance->this_id,
-	         hostdata->flags & FLAG_TAGGED_QUEUING ? "TAGGED_QUEUING " : "",
-	         hostdata->flags & FLAG_TOSHIBA_DELAY  ? "TOSHIBA_DELAY "  : "",
-#ifdef DIFFERENTIAL
-	         "DIFFERENTIAL "
-#endif
-#ifdef PARITY
-	         "PARITY "
-#endif
-#ifdef SUPPORT_TAGS
-	         "SUPPORT_TAGS "
-#endif
-	         "");
-}
-
-/**
- * NCR5380_init - initialise an NCR5380
- * @instance: adapter to configure
- * @flags: control flags
- *
- * Initializes *instance and corresponding 5380 chip,
- * with flags OR'd into the initial flags value.
- *
- * Notes : I assume that the host, hostno, and id bits have been
- * set correctly. I don't care about the irq and other fields.
- *
- * Returns 0 for success
- */
-
-static int __init NCR5380_init(struct Scsi_Host *instance, int flags)
-{
-	struct NCR5380_hostdata *hostdata = shost_priv(instance);
-	int i;
-	unsigned long deadline;
-
-	hostdata->host = instance;
-	hostdata->id_mask = 1 << instance->this_id;
-	hostdata->id_higher_mask = 0;
-	for (i = hostdata->id_mask; i <= 0x80; i <<= 1)
-		if (i > hostdata->id_mask)
-			hostdata->id_higher_mask |= i;
-	for (i = 0; i < 8; ++i)
-		hostdata->busy[i] = 0;
-#ifdef SUPPORT_TAGS
-	init_tags(hostdata);
-#endif
-	hostdata->dma_len = 0;
-
-	spin_lock_init(&hostdata->lock);
-	hostdata->connected = NULL;
-	hostdata->sensing = NULL;
-	INIT_LIST_HEAD(&hostdata->autosense);
-	INIT_LIST_HEAD(&hostdata->unissued);
-	INIT_LIST_HEAD(&hostdata->disconnected);
-
-	hostdata->flags = flags;
-
-	INIT_WORK(&hostdata->main_task, NCR5380_main);
-	hostdata->work_q = alloc_workqueue("ncr5380_%d",
-	                        WQ_UNBOUND | WQ_MEM_RECLAIM,
-	                        1, instance->host_no);
-	if (!hostdata->work_q)
-		return -ENOMEM;
-
-	prepare_info(instance);
-
-	NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
-	NCR5380_write(MODE_REG, MR_BASE);
-	NCR5380_write(TARGET_COMMAND_REG, 0);
-	NCR5380_write(SELECT_ENABLE_REG, 0);
-
-	/* Calibrate register polling loop */
-	i = 0;
-	deadline = jiffies + 1;
-	do {
-		cpu_relax();
-	} while (time_is_after_jiffies(deadline));
-	deadline += msecs_to_jiffies(256);
-	do {
-		NCR5380_read(STATUS_REG);
-		++i;
-		cpu_relax();
-	} while (time_is_after_jiffies(deadline));
-	hostdata->accesses_per_ms = i / 256;
-
-	return 0;
-}
-
-/**
- * NCR5380_maybe_reset_bus - Detect and correct bus wedge problems.
- * @instance: adapter to check
- *
- * If the system crashed, it may have crashed with a connected target and
- * the SCSI bus busy. Check for BUS FREE phase. If not, try to abort the
- * currently established nexus, which we know nothing about. Failing that
- * do a bus reset.
- *
- * Note that a bus reset will cause the chip to assert IRQ.
- *
- * Returns 0 if successful, otherwise -ENXIO.
- */
-
-static int NCR5380_maybe_reset_bus(struct Scsi_Host *instance)
-{
-	struct NCR5380_hostdata *hostdata = shost_priv(instance);
-	int pass;
-
-	for (pass = 1; (NCR5380_read(STATUS_REG) & SR_BSY) && pass <= 6; ++pass) {
-		switch (pass) {
-		case 1:
-		case 3:
-		case 5:
-			shost_printk(KERN_ERR, instance, "SCSI bus busy, waiting up to five seconds\n");
-			NCR5380_poll_politely(instance,
-			                      STATUS_REG, SR_BSY, 0, 5 * HZ);
-			break;
-		case 2:
-			shost_printk(KERN_ERR, instance, "bus busy, attempting abort\n");
-			do_abort(instance);
-			break;
-		case 4:
-			shost_printk(KERN_ERR, instance, "bus busy, attempting reset\n");
-			do_reset(instance);
-			/* Wait after a reset; the SCSI standard calls for
-			 * 250ms, we wait 500ms to be on the safe side.
-			 * But some Toshiba CD-ROMs need ten times that.
-			 */
-			if (hostdata->flags & FLAG_TOSHIBA_DELAY)
-				msleep(2500);
-			else
-				msleep(500);
-			break;
-		case 6:
-			shost_printk(KERN_ERR, instance, "bus locked solid\n");
-			return -ENXIO;
-		}
-	}
-	return 0;
-}
-
-/**
- * NCR5380_exit - remove an NCR5380
- * @instance: adapter to remove
- *
- * Assumes that no more work can be queued (e.g. by NCR5380_intr).
- */
-
-static void NCR5380_exit(struct Scsi_Host *instance)
-{
-	struct NCR5380_hostdata *hostdata = shost_priv(instance);
-
-	cancel_work_sync(&hostdata->main_task);
-	destroy_workqueue(hostdata->work_q);
-}
-
-/**
- * complete_cmd - finish processing a command and return it to the SCSI ML
- * @instance: the host instance
- * @cmd: command to complete
- */
-
-static void complete_cmd(struct Scsi_Host *instance,
-                         struct scsi_cmnd *cmd)
-{
-	struct NCR5380_hostdata *hostdata = shost_priv(instance);
-
-	dsprintk(NDEBUG_QUEUES, instance, "complete_cmd: cmd %p\n", cmd);
-
-	if (hostdata->sensing == cmd) {
-		/* Autosense processing ends here */
-		if ((cmd->result & 0xff) != SAM_STAT_GOOD) {
-			scsi_eh_restore_cmnd(cmd, &hostdata->ses);
-			set_host_byte(cmd, DID_ERROR);
-		} else
-			scsi_eh_restore_cmnd(cmd, &hostdata->ses);
-		hostdata->sensing = NULL;
-	}
-
-#ifdef SUPPORT_TAGS
-	cmd_free_tag(cmd);
-#else
-	hostdata->busy[scmd_id(cmd)] &= ~(1 << cmd->device->lun);
-#endif
-	cmd->scsi_done(cmd);
-}
-
-/**
- * NCR5380_queue_command - queue a command
- * @instance: the relevant SCSI adapter
- * @cmd: SCSI command
- *
- * cmd is added to the per-instance issue queue, with minor
- * twiddling done to the host specific fields of cmd.  If the
- * main coroutine is not running, it is restarted.
- */
-
-static int NCR5380_queue_command(struct Scsi_Host *instance,
-                                 struct scsi_cmnd *cmd)
-{
-	struct NCR5380_hostdata *hostdata = shost_priv(instance);
-	struct NCR5380_cmd *ncmd = scsi_cmd_priv(cmd);
-	unsigned long flags;
-
-#if (NDEBUG & NDEBUG_NO_WRITE)
-	switch (cmd->cmnd[0]) {
-	case WRITE_6:
-	case WRITE_10:
-		shost_printk(KERN_DEBUG, instance, "WRITE attempted with NDEBUG_NO_WRITE set\n");
-		cmd->result = (DID_ERROR << 16);
-		cmd->scsi_done(cmd);
-		return 0;
-	}
-#endif /* (NDEBUG & NDEBUG_NO_WRITE) */
-
-	cmd->result = 0;
-
-	/*
-	 * ++roman: Just disabling the NCR interrupt isn't sufficient here,
-	 * because also a timer int can trigger an abort or reset, which would
-	 * alter queues and touch the lock.
-	 */
-	if (!NCR5380_acquire_dma_irq(instance))
-		return SCSI_MLQUEUE_HOST_BUSY;
-
-	spin_lock_irqsave(&hostdata->lock, flags);
-
-	/*
-	 * Insert the cmd into the issue queue. Note that REQUEST SENSE
-	 * commands are added to the head of the queue since any command will
-	 * clear the contingent allegiance condition that exists and the
-	 * sense data is only guaranteed to be valid while the condition exists.
-	 */
-
-	if (cmd->cmnd[0] == REQUEST_SENSE)
-		list_add(&ncmd->list, &hostdata->unissued);
-	else
-		list_add_tail(&ncmd->list, &hostdata->unissued);
-
-	spin_unlock_irqrestore(&hostdata->lock, flags);
-
-	dsprintk(NDEBUG_QUEUES, instance, "command %p added to %s of queue\n",
-	         cmd, (cmd->cmnd[0] == REQUEST_SENSE) ? "head" : "tail");
-
-	/* Kick off command processing */
-	queue_work(hostdata->work_q, &hostdata->main_task);
-	return 0;
-}
-
-static inline void maybe_release_dma_irq(struct Scsi_Host *instance)
-{
-	struct NCR5380_hostdata *hostdata = shost_priv(instance);
-
-	/* Caller does the locking needed to set & test these data atomically */
-	if (list_empty(&hostdata->disconnected) &&
-	    list_empty(&hostdata->unissued) &&
-	    list_empty(&hostdata->autosense) &&
-	    !hostdata->connected &&
-	    !hostdata->selecting)
-		NCR5380_release_dma_irq(instance);
-}
-
-/**
- * dequeue_next_cmd - dequeue a command for processing
- * @instance: the scsi host instance
- *
- * Priority is given to commands on the autosense queue. These commands
- * need autosense because of a CHECK CONDITION result.
- *
- * Returns a command pointer if a command is found for a target that is
- * not already busy. Otherwise returns NULL.
- */
-
-static struct scsi_cmnd *dequeue_next_cmd(struct Scsi_Host *instance)
-{
-	struct NCR5380_hostdata *hostdata = shost_priv(instance);
-	struct NCR5380_cmd *ncmd;
-	struct scsi_cmnd *cmd;
-
-	if (hostdata->sensing || list_empty(&hostdata->autosense)) {
-		list_for_each_entry(ncmd, &hostdata->unissued, list) {
-			cmd = NCR5380_to_scmd(ncmd);
-			dsprintk(NDEBUG_QUEUES, instance, "dequeue: cmd=%p target=%d busy=0x%02x lun=%llu\n",
-			         cmd, scmd_id(cmd), hostdata->busy[scmd_id(cmd)], cmd->device->lun);
-
-			if (
-#ifdef SUPPORT_TAGS
-			    !is_lun_busy(cmd, 1)
-#else
-			    !(hostdata->busy[scmd_id(cmd)] & (1 << cmd->device->lun))
-#endif
-			) {
-				list_del(&ncmd->list);
-				dsprintk(NDEBUG_QUEUES, instance,
-				         "dequeue: removed %p from issue queue\n", cmd);
-				return cmd;
-			}
-		}
-	} else {
-		/* Autosense processing begins here */
-		ncmd = list_first_entry(&hostdata->autosense,
-		                        struct NCR5380_cmd, list);
-		list_del(&ncmd->list);
-		cmd = NCR5380_to_scmd(ncmd);
-		dsprintk(NDEBUG_QUEUES, instance,
-		         "dequeue: removed %p from autosense queue\n", cmd);
-		scsi_eh_prep_cmnd(cmd, &hostdata->ses, NULL, 0, ~0);
-		hostdata->sensing = cmd;
-		return cmd;
-	}
-	return NULL;
-}
-
-static void requeue_cmd(struct Scsi_Host *instance, struct scsi_cmnd *cmd)
-{
-	struct NCR5380_hostdata *hostdata = shost_priv(instance);
-	struct NCR5380_cmd *ncmd = scsi_cmd_priv(cmd);
-
-	if (hostdata->sensing == cmd) {
-		scsi_eh_restore_cmnd(cmd, &hostdata->ses);
-		list_add(&ncmd->list, &hostdata->autosense);
-		hostdata->sensing = NULL;
-	} else
-		list_add(&ncmd->list, &hostdata->unissued);
-}
-
-/**
- * NCR5380_main - NCR state machines
- *
- * NCR5380_main is a coroutine that runs as long as more work can
- * be done on the NCR5380 host adapters in a system.  Both
- * NCR5380_queue_command() and NCR5380_intr() will try to start it
- * in case it is not running.
- */
-
-static void NCR5380_main(struct work_struct *work)
-{
-	struct NCR5380_hostdata *hostdata =
-		container_of(work, struct NCR5380_hostdata, main_task);
-	struct Scsi_Host *instance = hostdata->host;
-	int done;
-
-	/*
-	 * ++roman: Just disabling the NCR interrupt isn't sufficient here,
-	 * because also a timer int can trigger an abort or reset, which can
-	 * alter queues and touch the Falcon lock.
-	 */
-
-	do {
-		done = 1;
-
-		spin_lock_irq(&hostdata->lock);
-		while (!hostdata->connected && !hostdata->selecting) {
-			struct scsi_cmnd *cmd = dequeue_next_cmd(instance);
-
-			if (!cmd)
-				break;
-
-			dsprintk(NDEBUG_MAIN, instance, "main: dequeued %p\n", cmd);
-
-			/*
-			 * Attempt to establish an I_T_L nexus here.
-			 * On success, instance->hostdata->connected is set.
-			 * On failure, we must add the command back to the
-			 * issue queue so we can keep trying.
-			 */
-			/*
-			 * REQUEST SENSE commands are issued without tagged
-			 * queueing, even on SCSI-II devices because the
-			 * contingent allegiance condition exists for the
-			 * entire unit.
-			 */
-			/* ++roman: ...and the standard also requires that
-			 * REQUEST SENSE command are untagged.
-			 */
-
-#ifdef SUPPORT_TAGS
-			cmd_get_tag(cmd, cmd->cmnd[0] != REQUEST_SENSE);
-#endif
-			if (!NCR5380_select(instance, cmd)) {
-				dsprintk(NDEBUG_MAIN, instance, "main: select complete\n");
-				maybe_release_dma_irq(instance);
-			} else {
-				dsprintk(NDEBUG_MAIN | NDEBUG_QUEUES, instance,
-				         "main: select failed, returning %p to queue\n", cmd);
-				requeue_cmd(instance, cmd);
-#ifdef SUPPORT_TAGS
-				cmd_free_tag(cmd);
-#endif
-			}
-		}
-		if (hostdata->connected && !hostdata->dma_len) {
-			dsprintk(NDEBUG_MAIN, instance, "main: performing information transfer\n");
-			NCR5380_information_transfer(instance);
-			done = 0;
-		}
-		spin_unlock_irq(&hostdata->lock);
-		if (!done)
-			cond_resched();
-	} while (!done);
-}
-
-
-/*
- * Function : void NCR5380_dma_complete (struct Scsi_Host *instance)
- *
- * Purpose : Called by interrupt handler when DMA finishes or a phase
- * mismatch occurs (which would finish the DMA transfer).
- *
- * Inputs : instance - this instance of the NCR5380.
- */
-
-static void NCR5380_dma_complete(struct Scsi_Host *instance)
-{
-	struct NCR5380_hostdata *hostdata = shost_priv(instance);
-	int transferred;
-	unsigned char **data;
-	int *count;
-	int saved_data = 0, overrun = 0;
-	unsigned char p;
-
-	if (hostdata->read_overruns) {
-		p = hostdata->connected->SCp.phase;
-		if (p & SR_IO) {
-			udelay(10);
-			if ((NCR5380_read(BUS_AND_STATUS_REG) &
-			     (BASR_PHASE_MATCH|BASR_ACK)) ==
-			    (BASR_PHASE_MATCH|BASR_ACK)) {
-				saved_data = NCR5380_read(INPUT_DATA_REG);
-				overrun = 1;
-				dsprintk(NDEBUG_DMA, instance, "read overrun handled\n");
-			}
-		}
-	}
-
-#if defined(CONFIG_SUN3)
-	if ((sun3scsi_dma_finish(rq_data_dir(hostdata->connected->request)))) {
-		pr_err("scsi%d: overrun in UDC counter -- not prepared to deal with this!\n",
-		       instance->host_no);
-		BUG();
-	}
-
-	/* make sure we're not stuck in a data phase */
-	if ((NCR5380_read(BUS_AND_STATUS_REG) & (BASR_PHASE_MATCH | BASR_ACK)) ==
-	    (BASR_PHASE_MATCH | BASR_ACK)) {
-		pr_err("scsi%d: BASR %02x\n", instance->host_no,
-		       NCR5380_read(BUS_AND_STATUS_REG));
-		pr_err("scsi%d: bus stuck in data phase -- probably a single byte overrun!\n",
-		       instance->host_no);
-		BUG();
-	}
-#endif
-
-	NCR5380_write(MODE_REG, MR_BASE);
-	NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
-	NCR5380_read(RESET_PARITY_INTERRUPT_REG);
-
-	transferred = hostdata->dma_len - NCR5380_dma_residual(instance);
-	hostdata->dma_len = 0;
-
-	data = (unsigned char **)&hostdata->connected->SCp.ptr;
-	count = &hostdata->connected->SCp.this_residual;
-	*data += transferred;
-	*count -= transferred;
-
-	if (hostdata->read_overruns) {
-		int cnt, toPIO;
-
-		if ((NCR5380_read(STATUS_REG) & PHASE_MASK) == p && (p & SR_IO)) {
-			cnt = toPIO = hostdata->read_overruns;
-			if (overrun) {
-				dprintk(NDEBUG_DMA, "Got an input overrun, using saved byte\n");
-				*(*data)++ = saved_data;
-				(*count)--;
-				cnt--;
-				toPIO--;
-			}
-			dprintk(NDEBUG_DMA, "Doing %d-byte PIO to 0x%08lx\n", cnt, (long)*data);
-			NCR5380_transfer_pio(instance, &p, &cnt, data);
-			*count -= toPIO - cnt;
-		}
-	}
-}
-
-
-/**
- * NCR5380_intr - generic NCR5380 irq handler
- * @irq: interrupt number
- * @dev_id: device info
- *
- * Handle interrupts, reestablishing I_T_L or I_T_L_Q nexuses
- * from the disconnected queue, and restarting NCR5380_main()
- * as required.
- *
- * The chip can assert IRQ in any of six different conditions. The IRQ flag
- * is then cleared by reading the Reset Parity/Interrupt Register (RPIR).
- * Three of these six conditions are latched in the Bus and Status Register:
- * - End of DMA (cleared by ending DMA Mode)
- * - Parity error (cleared by reading RPIR)
- * - Loss of BSY (cleared by reading RPIR)
- * Two conditions have flag bits that are not latched:
- * - Bus phase mismatch (non-maskable in DMA Mode, cleared by ending DMA Mode)
- * - Bus reset (non-maskable)
- * The remaining condition has no flag bit at all:
- * - Selection/reselection
- *
- * Hence, establishing the cause(s) of any interrupt is partly guesswork.
- * In "The DP8490 and DP5380 Comparison Guide", National Semiconductor
- * claimed that "the design of the [DP8490] interrupt logic ensures
- * interrupts will not be lost (they can be on the DP5380)."
- * The L5380/53C80 datasheet from LOGIC Devices has more details.
- *
- * Checking for bus reset by reading RST is futile because of interrupt
- * latency, but a bus reset will reset chip logic. Checking for parity error
- * is unnecessary because that interrupt is never enabled. A Loss of BSY
- * condition will clear DMA Mode. We can tell when this occurs because the
- * the Busy Monitor interrupt is enabled together with DMA Mode.
- */
-
-static irqreturn_t NCR5380_intr(int irq, void *dev_id)
-{
-	struct Scsi_Host *instance = dev_id;
-	struct NCR5380_hostdata *hostdata = shost_priv(instance);
-	int handled = 0;
-	unsigned char basr;
-	unsigned long flags;
-
-	spin_lock_irqsave(&hostdata->lock, flags);
-
-	basr = NCR5380_read(BUS_AND_STATUS_REG);
-	if (basr & BASR_IRQ) {
-		unsigned char mr = NCR5380_read(MODE_REG);
-		unsigned char sr = NCR5380_read(STATUS_REG);
-
-		dsprintk(NDEBUG_INTR, instance, "IRQ %d, BASR 0x%02x, SR 0x%02x, MR 0x%02x\n",
-		         irq, basr, sr, mr);
-
-		if ((mr & MR_DMA_MODE) || (mr & MR_MONITOR_BSY)) {
-			/* Probably End of DMA, Phase Mismatch or Loss of BSY.
-			 * We ack IRQ after clearing Mode Register. Workarounds
-			 * for End of DMA errata need to happen in DMA Mode.
-			 */
-
-			dsprintk(NDEBUG_INTR, instance, "interrupt in DMA mode\n");
-
-			if (hostdata->connected) {
-				NCR5380_dma_complete(instance);
-				queue_work(hostdata->work_q, &hostdata->main_task);
-			} else {
-				NCR5380_write(MODE_REG, MR_BASE);
-				NCR5380_read(RESET_PARITY_INTERRUPT_REG);
-			}
-		} else if ((NCR5380_read(CURRENT_SCSI_DATA_REG) & hostdata->id_mask) &&
-		    (sr & (SR_SEL | SR_IO | SR_BSY | SR_RST)) == (SR_SEL | SR_IO)) {
-			/* Probably reselected */
-			NCR5380_write(SELECT_ENABLE_REG, 0);
-			NCR5380_read(RESET_PARITY_INTERRUPT_REG);
-
-			dsprintk(NDEBUG_INTR, instance, "interrupt with SEL and IO\n");
-
-			if (!hostdata->connected) {
-				NCR5380_reselect(instance);
-				queue_work(hostdata->work_q, &hostdata->main_task);
-			}
-			if (!hostdata->connected)
-				NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
-		} else {
-			/* Probably Bus Reset */
-			NCR5380_read(RESET_PARITY_INTERRUPT_REG);
-
-			dsprintk(NDEBUG_INTR, instance, "unknown interrupt\n");
-#ifdef SUN3_SCSI_VME
-			dregs->csr |= CSR_DMA_ENABLE;
-#endif
-		}
-		handled = 1;
-	} else {
-		shost_printk(KERN_NOTICE, instance, "interrupt without IRQ bit\n");
-#ifdef SUN3_SCSI_VME
-		dregs->csr |= CSR_DMA_ENABLE;
-#endif
-	}
-
-	spin_unlock_irqrestore(&hostdata->lock, flags);
-
-	return IRQ_RETVAL(handled);
-}
-
-/*
- * Function : int NCR5380_select(struct Scsi_Host *instance,
- * struct scsi_cmnd *cmd)
- *
- * Purpose : establishes I_T_L or I_T_L_Q nexus for new or existing command,
- * including ARBITRATION, SELECTION, and initial message out for
- * IDENTIFY and queue messages.
- *
- * Inputs : instance - instantiation of the 5380 driver on which this
- * target lives, cmd - SCSI command to execute.
- *
- * Returns cmd if selection failed but should be retried,
- * NULL if selection failed and should not be retried, or
- * NULL if selection succeeded (hostdata->connected == cmd).
- *
- * Side effects :
- * If bus busy, arbitration failed, etc, NCR5380_select() will exit
- * with registers as they should have been on entry - ie
- * SELECT_ENABLE will be set appropriately, the NCR5380
- * will cease to drive any SCSI bus signals.
- *
- * If successful : I_T_L or I_T_L_Q nexus will be established,
- * instance->connected will be set to cmd.
- * SELECT interrupt will be disabled.
- *
- * If failed (no target) : cmd->scsi_done() will be called, and the
- * cmd->result host byte set to DID_BAD_TARGET.
- */
-
-static struct scsi_cmnd *NCR5380_select(struct Scsi_Host *instance,
-                                        struct scsi_cmnd *cmd)
-{
-	struct NCR5380_hostdata *hostdata = shost_priv(instance);
-	unsigned char tmp[3], phase;
-	unsigned char *data;
-	int len;
-	int err;
-
-	NCR5380_dprint(NDEBUG_ARBITRATION, instance);
-	dsprintk(NDEBUG_ARBITRATION, instance, "starting arbitration, id = %d\n",
-	         instance->this_id);
-
-	/*
-	 * Arbitration and selection phases are slow and involve dropping the
-	 * lock, so we have to watch out for EH. An exception handler may
-	 * change 'selecting' to NULL. This function will then return NULL
-	 * so that the caller will forget about 'cmd'. (During information
-	 * transfer phases, EH may change 'connected' to NULL.)
-	 */
-	hostdata->selecting = cmd;
-
-	/*
-	 * Set the phase bits to 0, otherwise the NCR5380 won't drive the
-	 * data bus during SELECTION.
-	 */
-
-	NCR5380_write(TARGET_COMMAND_REG, 0);
-
-	/*
-	 * Start arbitration.
-	 */
-
-	NCR5380_write(OUTPUT_DATA_REG, hostdata->id_mask);
-	NCR5380_write(MODE_REG, MR_ARBITRATE);
-
-	/* The chip now waits for BUS FREE phase. Then after the 800 ns
-	 * Bus Free Delay, arbitration will begin.
-	 */
-
-	spin_unlock_irq(&hostdata->lock);
-	err = NCR5380_poll_politely2(instance, MODE_REG, MR_ARBITRATE, 0,
-	                INITIATOR_COMMAND_REG, ICR_ARBITRATION_PROGRESS,
-	                                       ICR_ARBITRATION_PROGRESS, HZ);
-	spin_lock_irq(&hostdata->lock);
-	if (!(NCR5380_read(MODE_REG) & MR_ARBITRATE)) {
-		/* Reselection interrupt */
-		goto out;
-	}
-	if (!hostdata->selecting) {
-		/* Command was aborted */
-		NCR5380_write(MODE_REG, MR_BASE);
-		goto out;
-	}
-	if (err < 0) {
-		NCR5380_write(MODE_REG, MR_BASE);
-		shost_printk(KERN_ERR, instance,
-		             "select: arbitration timeout\n");
-		goto out;
-	}
-	spin_unlock_irq(&hostdata->lock);
-
-	/* The SCSI-2 arbitration delay is 2.4 us */
-	udelay(3);
-
-	/* Check for lost arbitration */
-	if ((NCR5380_read(INITIATOR_COMMAND_REG) & ICR_ARBITRATION_LOST) ||
-	    (NCR5380_read(CURRENT_SCSI_DATA_REG) & hostdata->id_higher_mask) ||
-	    (NCR5380_read(INITIATOR_COMMAND_REG) & ICR_ARBITRATION_LOST)) {
-		NCR5380_write(MODE_REG, MR_BASE);
-		dsprintk(NDEBUG_ARBITRATION, instance, "lost arbitration, deasserting MR_ARBITRATE\n");
-		spin_lock_irq(&hostdata->lock);
-		goto out;
-	}
-
-	/* After/during arbitration, BSY should be asserted.
-	 * IBM DPES-31080 Version S31Q works now
-	 * Tnx to Thomas_Roesch@m2.maus.de for finding this! (Roman)
-	 */
-	NCR5380_write(INITIATOR_COMMAND_REG,
-		      ICR_BASE | ICR_ASSERT_SEL | ICR_ASSERT_BSY);
-
-	/*
-	 * Again, bus clear + bus settle time is 1.2us, however, this is
-	 * a minimum so we'll udelay ceil(1.2)
-	 */
-
-	if (hostdata->flags & FLAG_TOSHIBA_DELAY)
-		udelay(15);
-	else
-		udelay(2);
-
-	spin_lock_irq(&hostdata->lock);
-
-	/* NCR5380_reselect() clears MODE_REG after a reselection interrupt */
-	if (!(NCR5380_read(MODE_REG) & MR_ARBITRATE))
-		goto out;
-
-	if (!hostdata->selecting) {
-		NCR5380_write(MODE_REG, MR_BASE);
-		NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
-		goto out;
-	}
-
-	dsprintk(NDEBUG_ARBITRATION, instance, "won arbitration\n");
-
-	/*
-	 * Now that we have won arbitration, start Selection process, asserting
-	 * the host and target ID's on the SCSI bus.
-	 */
-
-	NCR5380_write(OUTPUT_DATA_REG, hostdata->id_mask | (1 << scmd_id(cmd)));
-
-	/*
-	 * Raise ATN while SEL is true before BSY goes false from arbitration,
-	 * since this is the only way to guarantee that we'll get a MESSAGE OUT
-	 * phase immediately after selection.
-	 */
-
-	NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_BSY |
-	              ICR_ASSERT_DATA | ICR_ASSERT_ATN | ICR_ASSERT_SEL);
-	NCR5380_write(MODE_REG, MR_BASE);
-
-	/*
-	 * Reselect interrupts must be turned off prior to the dropping of BSY,
-	 * otherwise we will trigger an interrupt.
-	 */
-	NCR5380_write(SELECT_ENABLE_REG, 0);
-
-	spin_unlock_irq(&hostdata->lock);
-
-	/*
-	 * The initiator shall then wait at least two deskew delays and release
-	 * the BSY signal.
-	 */
-	udelay(1);        /* wingel -- wait two bus deskew delay >2*45ns */
-
-	/* Reset BSY */
-	NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_DATA |
-	              ICR_ASSERT_ATN | ICR_ASSERT_SEL);
-
-	/*
-	 * Something weird happens when we cease to drive BSY - looks
-	 * like the board/chip is letting us do another read before the
-	 * appropriate propagation delay has expired, and we're confusing
-	 * a BSY signal from ourselves as the target's response to SELECTION.
-	 *
-	 * A small delay (the 'C++' frontend breaks the pipeline with an
-	 * unnecessary jump, making it work on my 386-33/Trantor T128, the
-	 * tighter 'C' code breaks and requires this) solves the problem -
-	 * the 1 us delay is arbitrary, and only used because this delay will
-	 * be the same on other platforms and since it works here, it should
-	 * work there.
-	 *
-	 * wingel suggests that this could be due to failing to wait
-	 * one deskew delay.
-	 */
-
-	udelay(1);
-
-	dsprintk(NDEBUG_SELECTION, instance, "selecting target %d\n", scmd_id(cmd));
-
-	/*
-	 * The SCSI specification calls for a 250 ms timeout for the actual
-	 * selection.
-	 */
-
-	err = NCR5380_poll_politely(instance, STATUS_REG, SR_BSY, SR_BSY,
-	                            msecs_to_jiffies(250));
-
-	if ((NCR5380_read(STATUS_REG) & (SR_SEL | SR_IO)) == (SR_SEL | SR_IO)) {
-		spin_lock_irq(&hostdata->lock);
-		NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
-		NCR5380_reselect(instance);
-		if (!hostdata->connected)
-			NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
-		shost_printk(KERN_ERR, instance, "reselection after won arbitration?\n");
-		goto out;
-	}
-
-	if (err < 0) {
-		spin_lock_irq(&hostdata->lock);
-		NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
-		NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
-		/* Can't touch cmd if it has been reclaimed by the scsi ML */
-		if (hostdata->selecting) {
-			cmd->result = DID_BAD_TARGET << 16;
-			complete_cmd(instance, cmd);
-			dsprintk(NDEBUG_SELECTION, instance, "target did not respond within 250ms\n");
-			cmd = NULL;
-		}
-		goto out;
-	}
-
-	/*
-	 * No less than two deskew delays after the initiator detects the
-	 * BSY signal is true, it shall release the SEL signal and may
-	 * change the DATA BUS.                                     -wingel
-	 */
-
-	udelay(1);
-
-	NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_ATN);
-
-	/*
-	 * Since we followed the SCSI spec, and raised ATN while SEL
-	 * was true but before BSY was false during selection, the information
-	 * transfer phase should be a MESSAGE OUT phase so that we can send the
-	 * IDENTIFY message.
-	 *
-	 * If SCSI-II tagged queuing is enabled, we also send a SIMPLE_QUEUE_TAG
-	 * message (2 bytes) with a tag ID that we increment with every command
-	 * until it wraps back to 0.
-	 *
-	 * XXX - it turns out that there are some broken SCSI-II devices,
-	 * which claim to support tagged queuing but fail when more than
-	 * some number of commands are issued at once.
-	 */
-
-	/* Wait for start of REQ/ACK handshake */
-
-	err = NCR5380_poll_politely(instance, STATUS_REG, SR_REQ, SR_REQ, HZ);
-	spin_lock_irq(&hostdata->lock);
-	if (err < 0) {
-		shost_printk(KERN_ERR, instance, "select: REQ timeout\n");
-		NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
-		NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
-		goto out;
-	}
-	if (!hostdata->selecting) {
-		do_abort(instance);
-		goto out;
-	}
-
-	dsprintk(NDEBUG_SELECTION, instance, "target %d selected, going into MESSAGE OUT phase.\n",
-	         scmd_id(cmd));
-	tmp[0] = IDENTIFY(1, cmd->device->lun);
-
-#ifdef SUPPORT_TAGS
-	if (cmd->tag != TAG_NONE) {
-		tmp[1] = hostdata->last_message = SIMPLE_QUEUE_TAG;
-		tmp[2] = cmd->tag;
-		len = 3;
-	} else
-		len = 1;
-#else
-	len = 1;
-	cmd->tag = 0;
-#endif /* SUPPORT_TAGS */
-
-	/* Send message(s) */
-	data = tmp;
-	phase = PHASE_MSGOUT;
-	NCR5380_transfer_pio(instance, &phase, &len, &data);
-	dsprintk(NDEBUG_SELECTION, instance, "nexus established.\n");
-	/* XXX need to handle errors here */
-
-	hostdata->connected = cmd;
-#ifndef SUPPORT_TAGS
-	hostdata->busy[cmd->device->id] |= 1 << cmd->device->lun;
-#endif
-#ifdef SUN3_SCSI_VME
-	dregs->csr |= CSR_INTR;
-#endif
-
-	initialize_SCp(cmd);
-
-	cmd = NULL;
-
-out:
-	if (!hostdata->selecting)
-		return NULL;
-	hostdata->selecting = NULL;
-	return cmd;
-}
-
-/*
- * Function : int NCR5380_transfer_pio (struct Scsi_Host *instance,
- * unsigned char *phase, int *count, unsigned char **data)
- *
- * Purpose : transfers data in given phase using polled I/O
- *
- * Inputs : instance - instance of driver, *phase - pointer to
- * what phase is expected, *count - pointer to number of
- * bytes to transfer, **data - pointer to data pointer.
- *
- * Returns : -1 when different phase is entered without transferring
- * maximum number of bytes, 0 if all bytes are transferred or exit
- * is in same phase.
- *
- * Also, *phase, *count, *data are modified in place.
- *
- * XXX Note : handling for bus free may be useful.
- */
-
-/*
- * Note : this code is not as quick as it could be, however it
- * IS 100% reliable, and for the actual data transfer where speed
- * counts, we will always do a pseudo DMA or DMA transfer.
- */
-
-static int NCR5380_transfer_pio(struct Scsi_Host *instance,
-				unsigned char *phase, int *count,
-				unsigned char **data)
-{
-	unsigned char p = *phase, tmp;
-	int c = *count;
-	unsigned char *d = *data;
-
-	/*
-	 * The NCR5380 chip will only drive the SCSI bus when the
-	 * phase specified in the appropriate bits of the TARGET COMMAND
-	 * REGISTER match the STATUS REGISTER
-	 */
-
-	NCR5380_write(TARGET_COMMAND_REG, PHASE_SR_TO_TCR(p));
-
-	do {
-		/*
-		 * Wait for assertion of REQ, after which the phase bits will be
-		 * valid
-		 */
-
-		if (NCR5380_poll_politely(instance, STATUS_REG, SR_REQ, SR_REQ, HZ) < 0)
-			break;
-
-		dsprintk(NDEBUG_HANDSHAKE, instance, "REQ asserted\n");
-
-		/* Check for phase mismatch */
-		if ((NCR5380_read(STATUS_REG) & PHASE_MASK) != p) {
-			dsprintk(NDEBUG_PIO, instance, "phase mismatch\n");
-			NCR5380_dprint_phase(NDEBUG_PIO, instance);
-			break;
-		}
-
-		/* Do actual transfer from SCSI bus to / from memory */
-		if (!(p & SR_IO))
-			NCR5380_write(OUTPUT_DATA_REG, *d);
-		else
-			*d = NCR5380_read(CURRENT_SCSI_DATA_REG);
-
-		++d;
-
-		/*
-		 * The SCSI standard suggests that in MSGOUT phase, the initiator
-		 * should drop ATN on the last byte of the message phase
-		 * after REQ has been asserted for the handshake but before
-		 * the initiator raises ACK.
-		 */
-
-		if (!(p & SR_IO)) {
-			if (!((p & SR_MSG) && c > 1)) {
-				NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_DATA);
-				NCR5380_dprint(NDEBUG_PIO, instance);
-				NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE |
-				              ICR_ASSERT_DATA | ICR_ASSERT_ACK);
-			} else {
-				NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE |
-				              ICR_ASSERT_DATA | ICR_ASSERT_ATN);
-				NCR5380_dprint(NDEBUG_PIO, instance);
-				NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE |
-				              ICR_ASSERT_DATA | ICR_ASSERT_ATN | ICR_ASSERT_ACK);
-			}
-		} else {
-			NCR5380_dprint(NDEBUG_PIO, instance);
-			NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_ACK);
-		}
-
-		if (NCR5380_poll_politely(instance,
-		                          STATUS_REG, SR_REQ, 0, 5 * HZ) < 0)
-			break;
-
-		dsprintk(NDEBUG_HANDSHAKE, instance, "REQ negated, handshake complete\n");
-
-/*
- * We have several special cases to consider during REQ/ACK handshaking :
- * 1.  We were in MSGOUT phase, and we are on the last byte of the
- * message.  ATN must be dropped as ACK is dropped.
- *
- * 2.  We are in a MSGIN phase, and we are on the last byte of the
- * message.  We must exit with ACK asserted, so that the calling
- * code may raise ATN before dropping ACK to reject the message.
- *
- * 3.  ACK and ATN are clear and the target may proceed as normal.
- */
-		if (!(p == PHASE_MSGIN && c == 1)) {
-			if (p == PHASE_MSGOUT && c > 1)
-				NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_ATN);
-			else
-				NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
-		}
-	} while (--c);
-
-	dsprintk(NDEBUG_PIO, instance, "residual %d\n", c);
-
-	*count = c;
-	*data = d;
-	tmp = NCR5380_read(STATUS_REG);
-	/* The phase read from the bus is valid if either REQ is (already)
-	 * asserted or if ACK hasn't been released yet. The latter applies if
-	 * we're in MSG IN, DATA IN or STATUS and all bytes have been received.
-	 */
-	if ((tmp & SR_REQ) || ((tmp & SR_IO) && c == 0))
-		*phase = tmp & PHASE_MASK;
-	else
-		*phase = PHASE_UNKNOWN;
-
-	if (!c || (*phase == p))
-		return 0;
-	else
-		return -1;
-}
-
-/**
- * do_reset - issue a reset command
- * @instance: adapter to reset
- *
- * Issue a reset sequence to the NCR5380 and try and get the bus
- * back into sane shape.
- *
- * This clears the reset interrupt flag because there may be no handler for
- * it. When the driver is initialized, the NCR5380_intr() handler has not yet
- * been installed. And when in EH we may have released the ST DMA interrupt.
- */
-
-static void do_reset(struct Scsi_Host *instance)
-{
-	unsigned long flags;
-
-	local_irq_save(flags);
-	NCR5380_write(TARGET_COMMAND_REG,
-	              PHASE_SR_TO_TCR(NCR5380_read(STATUS_REG) & PHASE_MASK));
-	NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_RST);
-	udelay(50);
-	NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
-	(void)NCR5380_read(RESET_PARITY_INTERRUPT_REG);
-	local_irq_restore(flags);
-}
-
-/**
- * do_abort - abort the currently established nexus by going to
- * MESSAGE OUT phase and sending an ABORT message.
- * @instance: relevant scsi host instance
- *
- * Returns 0 on success, -1 on failure.
- */
-
-static int do_abort(struct Scsi_Host *instance)
-{
-	unsigned char *msgptr, phase, tmp;
-	int len;
-	int rc;
-
-	/* Request message out phase */
-	NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_ATN);
-
-	/*
-	 * Wait for the target to indicate a valid phase by asserting
-	 * REQ.  Once this happens, we'll have either a MSGOUT phase
-	 * and can immediately send the ABORT message, or we'll have some
-	 * other phase and will have to source/sink data.
-	 *
-	 * We really don't care what value was on the bus or what value
-	 * the target sees, so we just handshake.
-	 */
-
-	rc = NCR5380_poll_politely(instance, STATUS_REG, SR_REQ, SR_REQ, 10 * HZ);
-	if (rc < 0)
-		goto timeout;
-
-	tmp = NCR5380_read(STATUS_REG) & PHASE_MASK;
-
-	NCR5380_write(TARGET_COMMAND_REG, PHASE_SR_TO_TCR(tmp));
-
-	if (tmp != PHASE_MSGOUT) {
-		NCR5380_write(INITIATOR_COMMAND_REG,
-		              ICR_BASE | ICR_ASSERT_ATN | ICR_ASSERT_ACK);
-		rc = NCR5380_poll_politely(instance, STATUS_REG, SR_REQ, 0, 3 * HZ);
-		if (rc < 0)
-			goto timeout;
-		NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_ATN);
-	}
-
-	tmp = ABORT;
-	msgptr = &tmp;
-	len = 1;
-	phase = PHASE_MSGOUT;
-	NCR5380_transfer_pio(instance, &phase, &len, &msgptr);
-
-	/*
-	 * If we got here, and the command completed successfully,
-	 * we're about to go into bus free state.
-	 */
-
-	return len ? -1 : 0;
-
-timeout:
-	NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
-	return -1;
-}
-
-
-/*
- * Function : int NCR5380_transfer_dma (struct Scsi_Host *instance,
- * unsigned char *phase, int *count, unsigned char **data)
- *
- * Purpose : transfers data in given phase using either real
- * or pseudo DMA.
- *
- * Inputs : instance - instance of driver, *phase - pointer to
- * what phase is expected, *count - pointer to number of
- * bytes to transfer, **data - pointer to data pointer.
- *
- * Returns : -1 when different phase is entered without transferring
- * maximum number of bytes, 0 if all bytes or transferred or exit
- * is in same phase.
- *
- * Also, *phase, *count, *data are modified in place.
- */
-
-
-static int NCR5380_transfer_dma(struct Scsi_Host *instance,
-				unsigned char *phase, int *count,
-				unsigned char **data)
-{
-	struct NCR5380_hostdata *hostdata = shost_priv(instance);
-	register int c = *count;
-	register unsigned char p = *phase;
-
-#if defined(CONFIG_SUN3)
-	/* sanity check */
-	if (!sun3_dma_setup_done) {
-		pr_err("scsi%d: transfer_dma without setup!\n",
-		       instance->host_no);
-		BUG();
-	}
-	hostdata->dma_len = c;
-
-	dsprintk(NDEBUG_DMA, instance, "initializing DMA %s: length %d, address %p\n",
-	         (p & SR_IO) ? "receive" : "send", c, *data);
-
-	/* netbsd turns off ints here, why not be safe and do it too */
-
-	/* send start chain */
-	sun3scsi_dma_start(c, *data);
-
-	NCR5380_write(TARGET_COMMAND_REG, PHASE_SR_TO_TCR(p));
-	NCR5380_write(MODE_REG, MR_BASE | MR_DMA_MODE | MR_MONITOR_BSY |
-	                        MR_ENABLE_EOP_INTR);
-	if (p & SR_IO) {
-		NCR5380_write(INITIATOR_COMMAND_REG, 0);
-		NCR5380_write(START_DMA_INITIATOR_RECEIVE_REG, 0);
-	} else {
-		NCR5380_write(INITIATOR_COMMAND_REG, ICR_ASSERT_DATA);
-		NCR5380_write(START_DMA_SEND_REG, 0);
-	}
-
-#ifdef SUN3_SCSI_VME
-	dregs->csr |= CSR_DMA_ENABLE;
-#endif
-
-	sun3_dma_active = 1;
-
-#else /* !defined(CONFIG_SUN3) */
-	register unsigned char *d = *data;
-	unsigned char tmp;
-
-	if ((tmp = (NCR5380_read(STATUS_REG) & PHASE_MASK)) != p) {
-		*phase = tmp;
-		return -1;
-	}
-
-	if (hostdata->read_overruns && (p & SR_IO))
-		c -= hostdata->read_overruns;
-
-	dsprintk(NDEBUG_DMA, instance, "initializing DMA %s: length %d, address %p\n",
-	         (p & SR_IO) ? "receive" : "send", c, d);
-
-	NCR5380_write(TARGET_COMMAND_REG, PHASE_SR_TO_TCR(p));
-	NCR5380_write(MODE_REG, MR_BASE | MR_DMA_MODE | MR_MONITOR_BSY |
-	                        MR_ENABLE_EOP_INTR);
-
-	if (!(hostdata->flags & FLAG_LATE_DMA_SETUP)) {
-		/* On the Medusa, it is a must to initialize the DMA before
-		 * starting the NCR. This is also the cleaner way for the TT.
-		 */
-		hostdata->dma_len = (p & SR_IO) ?
-			NCR5380_dma_read_setup(instance, d, c) :
-			NCR5380_dma_write_setup(instance, d, c);
-	}
-
-	if (p & SR_IO)
-		NCR5380_write(START_DMA_INITIATOR_RECEIVE_REG, 0);
-	else {
-		NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_DATA);
-		NCR5380_write(START_DMA_SEND_REG, 0);
-	}
-
-	if (hostdata->flags & FLAG_LATE_DMA_SETUP) {
-		/* On the Falcon, the DMA setup must be done after the last */
-		/* NCR access, else the DMA setup gets trashed!
-		 */
-		hostdata->dma_len = (p & SR_IO) ?
-			NCR5380_dma_read_setup(instance, d, c) :
-			NCR5380_dma_write_setup(instance, d, c);
-	}
-#endif /* !defined(CONFIG_SUN3) */
-
-	return 0;
-}
-
-/*
- * Function : NCR5380_information_transfer (struct Scsi_Host *instance)
- *
- * Purpose : run through the various SCSI phases and do as the target
- * directs us to.  Operates on the currently connected command,
- * instance->connected.
- *
- * Inputs : instance, instance for which we are doing commands
- *
- * Side effects : SCSI things happen, the disconnected queue will be
- * modified if a command disconnects, *instance->connected will
- * change.
- *
- * XXX Note : we need to watch for bus free or a reset condition here
- * to recover from an unexpected bus free condition.
- */
-
-static void NCR5380_information_transfer(struct Scsi_Host *instance)
-{
-	struct NCR5380_hostdata *hostdata = shost_priv(instance);
-	unsigned char msgout = NOP;
-	int sink = 0;
-	int len;
-	int transfersize;
-	unsigned char *data;
-	unsigned char phase, tmp, extended_msg[10], old_phase = 0xff;
-	struct scsi_cmnd *cmd;
-
-#ifdef SUN3_SCSI_VME
-	dregs->csr |= CSR_INTR;
-#endif
-
-	while ((cmd = hostdata->connected)) {
-		struct NCR5380_cmd *ncmd = scsi_cmd_priv(cmd);
-
-		tmp = NCR5380_read(STATUS_REG);
-		/* We only have a valid SCSI phase when REQ is asserted */
-		if (tmp & SR_REQ) {
-			phase = (tmp & PHASE_MASK);
-			if (phase != old_phase) {
-				old_phase = phase;
-				NCR5380_dprint_phase(NDEBUG_INFORMATION, instance);
-			}
-#if defined(CONFIG_SUN3)
-			if (phase == PHASE_CMDOUT) {
-				void *d;
-				unsigned long count;
-
-				if (!cmd->SCp.this_residual && cmd->SCp.buffers_residual) {
-					count = cmd->SCp.buffer->length;
-					d = sg_virt(cmd->SCp.buffer);
-				} else {
-					count = cmd->SCp.this_residual;
-					d = cmd->SCp.ptr;
-				}
-				/* this command setup for dma yet? */
-				if (sun3_dma_setup_done != cmd &&
-				    sun3scsi_dma_xfer_len(count, cmd) > 0) {
-					sun3scsi_dma_setup(instance, d, count,
-					                   rq_data_dir(cmd->request));
-					sun3_dma_setup_done = cmd;
-				}
-#ifdef SUN3_SCSI_VME
-				dregs->csr |= CSR_INTR;
-#endif
-			}
-#endif /* CONFIG_SUN3 */
-
-			if (sink && (phase != PHASE_MSGOUT)) {
-				NCR5380_write(TARGET_COMMAND_REG, PHASE_SR_TO_TCR(tmp));
-
-				NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_ATN |
-				              ICR_ASSERT_ACK);
-				while (NCR5380_read(STATUS_REG) & SR_REQ)
-					;
-				NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE |
-				              ICR_ASSERT_ATN);
-				sink = 0;
-				continue;
-			}
-
-			switch (phase) {
-			case PHASE_DATAOUT:
-#if (NDEBUG & NDEBUG_NO_DATAOUT)
-				shost_printk(KERN_DEBUG, instance, "NDEBUG_NO_DATAOUT set, attempted DATAOUT aborted\n");
-				sink = 1;
-				do_abort(instance);
-				cmd->result = DID_ERROR << 16;
-				complete_cmd(instance, cmd);
-				hostdata->connected = NULL;
-				return;
-#endif
-			case PHASE_DATAIN:
-				/*
-				 * If there is no room left in the current buffer in the
-				 * scatter-gather list, move onto the next one.
-				 */
-
-				if (!cmd->SCp.this_residual && cmd->SCp.buffers_residual) {
-					++cmd->SCp.buffer;
-					--cmd->SCp.buffers_residual;
-					cmd->SCp.this_residual = cmd->SCp.buffer->length;
-					cmd->SCp.ptr = sg_virt(cmd->SCp.buffer);
-					merge_contiguous_buffers(cmd);
-					dsprintk(NDEBUG_INFORMATION, instance, "%d bytes and %d buffers left\n",
-					         cmd->SCp.this_residual,
-					         cmd->SCp.buffers_residual);
-				}
-
-				/*
-				 * The preferred transfer method is going to be
-				 * PSEUDO-DMA for systems that are strictly PIO,
-				 * since we can let the hardware do the handshaking.
-				 *
-				 * For this to work, we need to know the transfersize
-				 * ahead of time, since the pseudo-DMA code will sit
-				 * in an unconditional loop.
-				 */
-
-#if !defined(CONFIG_SUN3)
-				transfersize = 0;
-				if (!cmd->device->borken)
-#endif
-					transfersize = NCR5380_dma_xfer_len(instance, cmd, phase);
-
-				if (transfersize > 0) {
-					len = transfersize;
-					cmd->SCp.phase = phase;
-					if (NCR5380_transfer_dma(instance, &phase,
-					    &len, (unsigned char **)&cmd->SCp.ptr)) {
-						/*
-						 * If the watchdog timer fires, all future
-						 * accesses to this device will use the
-						 * polled-IO.
-						 */
-						scmd_printk(KERN_INFO, cmd,
-							"switching to slow handshake\n");
-						cmd->device->borken = 1;
-						sink = 1;
-						do_abort(instance);
-						cmd->result = DID_ERROR << 16;
-						/* XXX - need to source or sink data here, as appropriate */
-					} else
-						return;
-				} else {
-					/* Break up transfer into 3 ms chunks,
-					 * presuming 6 accesses per handshake.
-					 */
-					transfersize = min((unsigned long)cmd->SCp.this_residual,
-					                   hostdata->accesses_per_ms / 2);
-					len = transfersize;
-					NCR5380_transfer_pio(instance, &phase, &len,
-					                     (unsigned char **)&cmd->SCp.ptr);
-					cmd->SCp.this_residual -= transfersize - len;
-				}
-#if defined(CONFIG_SUN3)
-				/* if we had intended to dma that command clear it */
-				if (sun3_dma_setup_done == cmd)
-					sun3_dma_setup_done = NULL;
-#endif
-				return;
-			case PHASE_MSGIN:
-				len = 1;
-				data = &tmp;
-				NCR5380_transfer_pio(instance, &phase, &len, &data);
-				cmd->SCp.Message = tmp;
-
-				switch (tmp) {
-				case ABORT:
-				case COMMAND_COMPLETE:
-					/* Accept message by clearing ACK */
-					NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
-					dsprintk(NDEBUG_QUEUES, instance,
-					         "COMMAND COMPLETE %p target %d lun %llu\n",
-					         cmd, scmd_id(cmd), cmd->device->lun);
-
-					hostdata->connected = NULL;
-#ifdef SUPPORT_TAGS
-					cmd_free_tag(cmd);
-					if (status_byte(cmd->SCp.Status) == QUEUE_FULL) {
-						u8 lun = cmd->device->lun;
-						struct tag_alloc *ta = &hostdata->TagAlloc[scmd_id(cmd)][lun];
-
-						dsprintk(NDEBUG_TAGS, instance,
-						         "QUEUE_FULL %p target %d lun %d nr_allocated %d\n",
-						         cmd, scmd_id(cmd), lun, ta->nr_allocated);
-						if (ta->queue_size > ta->nr_allocated)
-							ta->queue_size = ta->nr_allocated;
-					}
-#endif
-
-					cmd->result &= ~0xffff;
-					cmd->result |= cmd->SCp.Status;
-					cmd->result |= cmd->SCp.Message << 8;
-
-					if (cmd->cmnd[0] == REQUEST_SENSE)
-						complete_cmd(instance, cmd);
-					else {
-						if (cmd->SCp.Status == SAM_STAT_CHECK_CONDITION ||
-						    cmd->SCp.Status == SAM_STAT_COMMAND_TERMINATED) {
-							dsprintk(NDEBUG_QUEUES, instance, "autosense: adding cmd %p to tail of autosense queue\n",
-							         cmd);
-							list_add_tail(&ncmd->list,
-							              &hostdata->autosense);
-						} else
-							complete_cmd(instance, cmd);
-					}
-
-					/*
-					 * Restore phase bits to 0 so an interrupted selection,
-					 * arbitration can resume.
-					 */
-					NCR5380_write(TARGET_COMMAND_REG, 0);
-
-					/* Enable reselect interrupts */
-					NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
-
-					maybe_release_dma_irq(instance);
-					return;
-				case MESSAGE_REJECT:
-					/* Accept message by clearing ACK */
-					NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
-					switch (hostdata->last_message) {
-					case HEAD_OF_QUEUE_TAG:
-					case ORDERED_QUEUE_TAG:
-					case SIMPLE_QUEUE_TAG:
-						/* The target obviously doesn't support tagged
-						 * queuing, even though it announced this ability in
-						 * its INQUIRY data ?!? (maybe only this LUN?) Ok,
-						 * clear 'tagged_supported' and lock the LUN, since
-						 * the command is treated as untagged further on.
-						 */
-						cmd->device->tagged_supported = 0;
-						hostdata->busy[cmd->device->id] |= (1 << cmd->device->lun);
-						cmd->tag = TAG_NONE;
-						dsprintk(NDEBUG_TAGS, instance, "target %d lun %llu rejected QUEUE_TAG message; tagged queuing disabled\n",
-						         scmd_id(cmd), cmd->device->lun);
-						break;
-					}
-					break;
-				case DISCONNECT:
-					/* Accept message by clearing ACK */
-					NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
-					hostdata->connected = NULL;
-					list_add(&ncmd->list, &hostdata->disconnected);
-					dsprintk(NDEBUG_INFORMATION | NDEBUG_QUEUES,
-					         instance, "connected command %p for target %d lun %llu moved to disconnected queue\n",
-					         cmd, scmd_id(cmd), cmd->device->lun);
-
-					/*
-					 * Restore phase bits to 0 so an interrupted selection,
-					 * arbitration can resume.
-					 */
-					NCR5380_write(TARGET_COMMAND_REG, 0);
-
-					/* Enable reselect interrupts */
-					NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
-#ifdef SUN3_SCSI_VME
-					dregs->csr |= CSR_DMA_ENABLE;
-#endif
-					return;
-					/*
-					 * The SCSI data pointer is *IMPLICITLY* saved on a disconnect
-					 * operation, in violation of the SCSI spec so we can safely
-					 * ignore SAVE/RESTORE pointers calls.
-					 *
-					 * Unfortunately, some disks violate the SCSI spec and
-					 * don't issue the required SAVE_POINTERS message before
-					 * disconnecting, and we have to break spec to remain
-					 * compatible.
-					 */
-				case SAVE_POINTERS:
-				case RESTORE_POINTERS:
-					/* Accept message by clearing ACK */
-					NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
-					break;
-				case EXTENDED_MESSAGE:
-					/*
-					 * Start the message buffer with the EXTENDED_MESSAGE
-					 * byte, since spi_print_msg() wants the whole thing.
-					 */
-					extended_msg[0] = EXTENDED_MESSAGE;
-					/* Accept first byte by clearing ACK */
-					NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
-
-					spin_unlock_irq(&hostdata->lock);
-
-					dsprintk(NDEBUG_EXTENDED, instance, "receiving extended message\n");
-
-					len = 2;
-					data = extended_msg + 1;
-					phase = PHASE_MSGIN;
-					NCR5380_transfer_pio(instance, &phase, &len, &data);
-					dsprintk(NDEBUG_EXTENDED, instance, "length %d, code 0x%02x\n",
-					         (int)extended_msg[1],
-					         (int)extended_msg[2]);
-
-					if (!len && extended_msg[1] > 0 &&
-					    extended_msg[1] <= sizeof(extended_msg) - 2) {
-						/* Accept third byte by clearing ACK */
-						NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
-						len = extended_msg[1] - 1;
-						data = extended_msg + 3;
-						phase = PHASE_MSGIN;
-
-						NCR5380_transfer_pio(instance, &phase, &len, &data);
-						dsprintk(NDEBUG_EXTENDED, instance, "message received, residual %d\n",
-						         len);
-
-						switch (extended_msg[2]) {
-						case EXTENDED_SDTR:
-						case EXTENDED_WDTR:
-						case EXTENDED_MODIFY_DATA_POINTER:
-						case EXTENDED_EXTENDED_IDENTIFY:
-							tmp = 0;
-						}
-					} else if (len) {
-						shost_printk(KERN_ERR, instance, "error receiving extended message\n");
-						tmp = 0;
-					} else {
-						shost_printk(KERN_NOTICE, instance, "extended message code %02x length %d is too long\n",
-						             extended_msg[2], extended_msg[1]);
-						tmp = 0;
-					}
-
-					spin_lock_irq(&hostdata->lock);
-					if (!hostdata->connected)
-						return;
-
-					/* Fall through to reject message */
-
-					/*
-					 * If we get something weird that we aren't expecting,
-					 * reject it.
-					 */
-				default:
-					if (!tmp) {
-						shost_printk(KERN_ERR, instance, "rejecting message ");
-						spi_print_msg(extended_msg);
-						printk("\n");
-					} else if (tmp != EXTENDED_MESSAGE)
-						scmd_printk(KERN_INFO, cmd,
-						            "rejecting unknown message %02x\n",
-						            tmp);
-					else
-						scmd_printk(KERN_INFO, cmd,
-						            "rejecting unknown extended message code %02x, length %d\n",
-						            extended_msg[1], extended_msg[0]);
-
-					msgout = MESSAGE_REJECT;
-					NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_ATN);
-					break;
-				} /* switch (tmp) */
-				break;
-			case PHASE_MSGOUT:
-				len = 1;
-				data = &msgout;
-				hostdata->last_message = msgout;
-				NCR5380_transfer_pio(instance, &phase, &len, &data);
-				if (msgout == ABORT) {
-					hostdata->connected = NULL;
-					cmd->result = DID_ERROR << 16;
-					complete_cmd(instance, cmd);
-					maybe_release_dma_irq(instance);
-					NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
-					return;
-				}
-				msgout = NOP;
-				break;
-			case PHASE_CMDOUT:
-				len = cmd->cmd_len;
-				data = cmd->cmnd;
-				/*
-				 * XXX for performance reasons, on machines with a
-				 * PSEUDO-DMA architecture we should probably
-				 * use the dma transfer function.
-				 */
-				NCR5380_transfer_pio(instance, &phase, &len, &data);
-				break;
-			case PHASE_STATIN:
-				len = 1;
-				data = &tmp;
-				NCR5380_transfer_pio(instance, &phase, &len, &data);
-				cmd->SCp.Status = tmp;
-				break;
-			default:
-				shost_printk(KERN_ERR, instance, "unknown phase\n");
-				NCR5380_dprint(NDEBUG_ANY, instance);
-			} /* switch(phase) */
-		} else {
-			spin_unlock_irq(&hostdata->lock);
-			NCR5380_poll_politely(instance, STATUS_REG, SR_REQ, SR_REQ, HZ);
-			spin_lock_irq(&hostdata->lock);
-		}
-	}
-}
-
-/*
- * Function : void NCR5380_reselect (struct Scsi_Host *instance)
- *
- * Purpose : does reselection, initializing the instance->connected
- * field to point to the scsi_cmnd for which the I_T_L or I_T_L_Q
- * nexus has been reestablished,
- *
- * Inputs : instance - this instance of the NCR5380.
- */
-
-
-/* it might eventually prove necessary to do a dma setup on
-   reselection, but it doesn't seem to be needed now -- sam */
-
-static void NCR5380_reselect(struct Scsi_Host *instance)
-{
-	struct NCR5380_hostdata *hostdata = shost_priv(instance);
-	unsigned char target_mask;
-	unsigned char lun;
-#ifdef SUPPORT_TAGS
-	unsigned char tag;
-#endif
-	unsigned char msg[3];
-	int __maybe_unused len;
-	unsigned char __maybe_unused *data, __maybe_unused phase;
-	struct NCR5380_cmd *ncmd;
-	struct scsi_cmnd *tmp;
-
-	/*
-	 * Disable arbitration, etc. since the host adapter obviously
-	 * lost, and tell an interrupted NCR5380_select() to restart.
-	 */
-
-	NCR5380_write(MODE_REG, MR_BASE);
-
-	target_mask = NCR5380_read(CURRENT_SCSI_DATA_REG) & ~(hostdata->id_mask);
-
-	dsprintk(NDEBUG_RESELECTION, instance, "reselect\n");
-
-	/*
-	 * At this point, we have detected that our SCSI ID is on the bus,
-	 * SEL is true and BSY was false for at least one bus settle delay
-	 * (400 ns).
-	 *
-	 * We must assert BSY ourselves, until the target drops the SEL
-	 * signal.
-	 */
-
-	NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_BSY);
-	if (NCR5380_poll_politely(instance,
-	                          STATUS_REG, SR_SEL, 0, 2 * HZ) < 0) {
-		NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
-		return;
-	}
-	NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
-
-	/*
-	 * Wait for target to go into MSGIN.
-	 */
-
-	if (NCR5380_poll_politely(instance,
-	                          STATUS_REG, SR_REQ, SR_REQ, 2 * HZ) < 0) {
-		do_abort(instance);
-		return;
-	}
-
-#if defined(CONFIG_SUN3)
-	/* acknowledge toggle to MSGIN */
-	NCR5380_write(TARGET_COMMAND_REG, PHASE_SR_TO_TCR(PHASE_MSGIN));
-
-	/* peek at the byte without really hitting the bus */
-	msg[0] = NCR5380_read(CURRENT_SCSI_DATA_REG);
-#else
-	len = 1;
-	data = msg;
-	phase = PHASE_MSGIN;
-	NCR5380_transfer_pio(instance, &phase, &len, &data);
-
-	if (len) {
-		do_abort(instance);
-		return;
-	}
-#endif
-
-	if (!(msg[0] & 0x80)) {
-		shost_printk(KERN_ERR, instance, "expecting IDENTIFY message, got ");
-		spi_print_msg(msg);
-		printk("\n");
-		do_abort(instance);
-		return;
-	}
-	lun = msg[0] & 0x07;
-
-#if defined(SUPPORT_TAGS) && !defined(CONFIG_SUN3)
-	/* If the phase is still MSGIN, the target wants to send some more
-	 * messages. In case it supports tagged queuing, this is probably a
-	 * SIMPLE_QUEUE_TAG for the I_T_L_Q nexus.
-	 */
-	tag = TAG_NONE;
-	if (phase == PHASE_MSGIN && (hostdata->flags & FLAG_TAGGED_QUEUING)) {
-		/* Accept previous IDENTIFY message by clearing ACK */
-		NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
-		len = 2;
-		data = msg + 1;
-		if (!NCR5380_transfer_pio(instance, &phase, &len, &data) &&
-		    msg[1] == SIMPLE_QUEUE_TAG)
-			tag = msg[2];
-		dsprintk(NDEBUG_TAGS, instance, "reselect: target mask %02x, lun %d sent tag %d\n",
-		         target_mask, lun, tag);
-	}
-#endif
-
-	/*
-	 * Find the command corresponding to the I_T_L or I_T_L_Q  nexus we
-	 * just reestablished, and remove it from the disconnected queue.
-	 */
-
-	tmp = NULL;
-	list_for_each_entry(ncmd, &hostdata->disconnected, list) {
-		struct scsi_cmnd *cmd = NCR5380_to_scmd(ncmd);
-
-		if (target_mask == (1 << scmd_id(cmd)) &&
-		    lun == (u8)cmd->device->lun
-#ifdef SUPPORT_TAGS
-		    && (tag == cmd->tag)
-#endif
-		    ) {
-			list_del(&ncmd->list);
-			tmp = cmd;
-			break;
-		}
-	}
-
-	if (tmp) {
-		dsprintk(NDEBUG_RESELECTION | NDEBUG_QUEUES, instance,
-		         "reselect: removed %p from disconnected queue\n", tmp);
-	} else {
-
-#ifdef SUPPORT_TAGS
-		shost_printk(KERN_ERR, instance, "target bitmask 0x%02x lun %d tag %d not in disconnected queue.\n",
-		             target_mask, lun, tag);
-#else
-		shost_printk(KERN_ERR, instance, "target bitmask 0x%02x lun %d not in disconnected queue.\n",
-		             target_mask, lun);
-#endif
-		/*
-		 * Since we have an established nexus that we can't do anything
-		 * with, we must abort it.
-		 */
-		do_abort(instance);
-		return;
-	}
-
-#if defined(CONFIG_SUN3)
-	/* engage dma setup for the command we just saw */
-	{
-		void *d;
-		unsigned long count;
-
-		if (!tmp->SCp.this_residual && tmp->SCp.buffers_residual) {
-			count = tmp->SCp.buffer->length;
-			d = sg_virt(tmp->SCp.buffer);
-		} else {
-			count = tmp->SCp.this_residual;
-			d = tmp->SCp.ptr;
-		}
-		/* setup this command for dma if not already */
-		if (sun3_dma_setup_done != tmp &&
-		    sun3scsi_dma_xfer_len(count, tmp) > 0) {
-			sun3scsi_dma_setup(instance, d, count,
-			                   rq_data_dir(tmp->request));
-			sun3_dma_setup_done = tmp;
-		}
-	}
-
-	NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_ACK);
-#endif
-
-	/* Accept message by clearing ACK */
-	NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
-
-#if defined(SUPPORT_TAGS) && defined(CONFIG_SUN3)
-	/* If the phase is still MSGIN, the target wants to send some more
-	 * messages. In case it supports tagged queuing, this is probably a
-	 * SIMPLE_QUEUE_TAG for the I_T_L_Q nexus.
-	 */
-	tag = TAG_NONE;
-	if (phase == PHASE_MSGIN && setup_use_tagged_queuing) {
-		/* Accept previous IDENTIFY message by clearing ACK */
-		NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
-		len = 2;
-		data = msg + 1;
-		if (!NCR5380_transfer_pio(instance, &phase, &len, &data) &&
-		    msg[1] == SIMPLE_QUEUE_TAG)
-			tag = msg[2];
-		dsprintk(NDEBUG_TAGS, instance, "reselect: target mask %02x, lun %d sent tag %d\n"
-		         target_mask, lun, tag);
-	}
-#endif
-
-	hostdata->connected = tmp;
-	dsprintk(NDEBUG_RESELECTION, instance, "nexus established, target %d, lun %llu, tag %d\n",
-	         scmd_id(tmp), tmp->device->lun, tmp->tag);
-}
-
-
-/**
- * list_find_cmd - test for presence of a command in a linked list
- * @haystack: list of commands
- * @needle: command to search for
- */
-
-static bool list_find_cmd(struct list_head *haystack,
-                          struct scsi_cmnd *needle)
-{
-	struct NCR5380_cmd *ncmd;
-
-	list_for_each_entry(ncmd, haystack, list)
-		if (NCR5380_to_scmd(ncmd) == needle)
-			return true;
-	return false;
-}
-
-/**
- * list_remove_cmd - remove a command from linked list
- * @haystack: list of commands
- * @needle: command to remove
- */
-
-static bool list_del_cmd(struct list_head *haystack,
-                         struct scsi_cmnd *needle)
-{
-	if (list_find_cmd(haystack, needle)) {
-		struct NCR5380_cmd *ncmd = scsi_cmd_priv(needle);
-
-		list_del(&ncmd->list);
-		return true;
-	}
-	return false;
-}
-
-/**
- * NCR5380_abort - scsi host eh_abort_handler() method
- * @cmd: the command to be aborted
- *
- * Try to abort a given command by removing it from queues and/or sending
- * the target an abort message. This may not succeed in causing a target
- * to abort the command. Nonetheless, the low-level driver must forget about
- * the command because the mid-layer reclaims it and it may be re-issued.
- *
- * The normal path taken by a command is as follows. For EH we trace this
- * same path to locate and abort the command.
- *
- * unissued -> selecting -> [unissued -> selecting ->]... connected ->
- * [disconnected -> connected ->]...
- * [autosense -> connected ->] done
- *
- * If cmd was not found at all then presumably it has already been completed,
- * in which case return SUCCESS to try to avoid further EH measures.
- *
- * If the command has not completed yet, we must not fail to find it.
- * We have no option but to forget the aborted command (even if it still
- * lacks sense data). The mid-layer may re-issue a command that is in error
- * recovery (see scsi_send_eh_cmnd), but the logic and data structures in
- * this driver are such that a command can appear on one queue only.
- *
- * The lock protects driver data structures, but EH handlers also use it
- * to serialize their own execution and prevent their own re-entry.
- */
-
-static int NCR5380_abort(struct scsi_cmnd *cmd)
-{
-	struct Scsi_Host *instance = cmd->device->host;
-	struct NCR5380_hostdata *hostdata = shost_priv(instance);
-	unsigned long flags;
-	int result = SUCCESS;
-
-	spin_lock_irqsave(&hostdata->lock, flags);
-
-#if (NDEBUG & NDEBUG_ANY)
-	scmd_printk(KERN_INFO, cmd, __func__);
-#endif
-	NCR5380_dprint(NDEBUG_ANY, instance);
-	NCR5380_dprint_phase(NDEBUG_ANY, instance);
-
-	if (list_del_cmd(&hostdata->unissued, cmd)) {
-		dsprintk(NDEBUG_ABORT, instance,
-		         "abort: removed %p from issue queue\n", cmd);
-		cmd->result = DID_ABORT << 16;
-		cmd->scsi_done(cmd); /* No tag or busy flag to worry about */
-		goto out;
-	}
-
-	if (hostdata->selecting == cmd) {
-		dsprintk(NDEBUG_ABORT, instance,
-		         "abort: cmd %p == selecting\n", cmd);
-		hostdata->selecting = NULL;
-		cmd->result = DID_ABORT << 16;
-		complete_cmd(instance, cmd);
-		goto out;
-	}
-
-	if (list_del_cmd(&hostdata->disconnected, cmd)) {
-		dsprintk(NDEBUG_ABORT, instance,
-		         "abort: removed %p from disconnected list\n", cmd);
-		/* Can't call NCR5380_select() and send ABORT because that
-		 * means releasing the lock. Need a bus reset.
-		 */
-		set_host_byte(cmd, DID_ERROR);
-		complete_cmd(instance, cmd);
-		result = FAILED;
-		goto out;
-	}
-
-	if (hostdata->connected == cmd) {
-		dsprintk(NDEBUG_ABORT, instance, "abort: cmd %p is connected\n", cmd);
-		hostdata->connected = NULL;
-		hostdata->dma_len = 0;
-		if (do_abort(instance)) {
-			set_host_byte(cmd, DID_ERROR);
-			complete_cmd(instance, cmd);
-			result = FAILED;
-			goto out;
-		}
-		set_host_byte(cmd, DID_ABORT);
-		complete_cmd(instance, cmd);
-		goto out;
-	}
-
-	if (list_del_cmd(&hostdata->autosense, cmd)) {
-		dsprintk(NDEBUG_ABORT, instance,
-		         "abort: removed %p from sense queue\n", cmd);
-		set_host_byte(cmd, DID_ERROR);
-		complete_cmd(instance, cmd);
-	}
-
-out:
-	if (result == FAILED)
-		dsprintk(NDEBUG_ABORT, instance, "abort: failed to abort %p\n", cmd);
-	else
-		dsprintk(NDEBUG_ABORT, instance, "abort: successfully aborted %p\n", cmd);
-
-	queue_work(hostdata->work_q, &hostdata->main_task);
-	maybe_release_dma_irq(instance);
-	spin_unlock_irqrestore(&hostdata->lock, flags);
-
-	return result;
-}
-
-
-/**
- * NCR5380_bus_reset - reset the SCSI bus
- * @cmd: SCSI command undergoing EH
- *
- * Returns SUCCESS
- */
-
-static int NCR5380_bus_reset(struct scsi_cmnd *cmd)
-{
-	struct Scsi_Host *instance = cmd->device->host;
-	struct NCR5380_hostdata *hostdata = shost_priv(instance);
-	int i;
-	unsigned long flags;
-	struct NCR5380_cmd *ncmd;
-
-	spin_lock_irqsave(&hostdata->lock, flags);
-
-#if (NDEBUG & NDEBUG_ANY)
-	scmd_printk(KERN_INFO, cmd, __func__);
-#endif
-	NCR5380_dprint(NDEBUG_ANY, instance);
-	NCR5380_dprint_phase(NDEBUG_ANY, instance);
-
-	do_reset(instance);
-
-	/* reset NCR registers */
-	NCR5380_write(MODE_REG, MR_BASE);
-	NCR5380_write(TARGET_COMMAND_REG, 0);
-	NCR5380_write(SELECT_ENABLE_REG, 0);
-
-	/* After the reset, there are no more connected or disconnected commands
-	 * and no busy units; so clear the low-level status here to avoid
-	 * conflicts when the mid-level code tries to wake up the affected
-	 * commands!
-	 */
-
-	if (list_del_cmd(&hostdata->unissued, cmd)) {
-		cmd->result = DID_RESET << 16;
-		cmd->scsi_done(cmd);
-	}
-
-	if (hostdata->selecting) {
-		hostdata->selecting->result = DID_RESET << 16;
-		complete_cmd(instance, hostdata->selecting);
-		hostdata->selecting = NULL;
-	}
-
-	list_for_each_entry(ncmd, &hostdata->disconnected, list) {
-		struct scsi_cmnd *cmd = NCR5380_to_scmd(ncmd);
-
-		set_host_byte(cmd, DID_RESET);
-		cmd->scsi_done(cmd);
-	}
-	INIT_LIST_HEAD(&hostdata->disconnected);
-
-	list_for_each_entry(ncmd, &hostdata->autosense, list) {
-		struct scsi_cmnd *cmd = NCR5380_to_scmd(ncmd);
-
-		set_host_byte(cmd, DID_RESET);
-		cmd->scsi_done(cmd);
-	}
-	INIT_LIST_HEAD(&hostdata->autosense);
-
-	if (hostdata->connected) {
-		set_host_byte(hostdata->connected, DID_RESET);
-		complete_cmd(instance, hostdata->connected);
-		hostdata->connected = NULL;
-	}
-
-#ifdef SUPPORT_TAGS
-	free_all_tags(hostdata);
-#endif
-	for (i = 0; i < 8; ++i)
-		hostdata->busy[i] = 0;
-	hostdata->dma_len = 0;
-
-	queue_work(hostdata->work_q, &hostdata->main_task);
-	maybe_release_dma_irq(instance);
-	spin_unlock_irqrestore(&hostdata->lock, flags);
-
-	return SUCCESS;
-}

^ permalink raw reply	[flat|nested] 60+ messages in thread

* [PATCH v4 13/23] ncr5380: Remove disused atari_NCR5380.c core driver
@ 2016-03-23 10:10   ` Finn Thain
  0 siblings, 0 replies; 60+ messages in thread
From: Finn Thain @ 2016-03-23 10:10 UTC (permalink / raw)
  To: James E.J. Bottomley, Martin K. Petersen, Michael Schmitz,
	linux-m68k, linux-scsi, linux-kernel
  Cc: Ondrej Zary, Sam Creasey

[-- Attachment #1: ncr5380-remove-disused-code --]
[-- Type: text/plain, Size: 91584 bytes --]

Now that atari_scsi and sun3_scsi have been converted to use the NCR5380.c
core driver, remove atari_NCR5380.c. Also remove the last vestiges of its
Tagged Command Queueing implementation from the wrapper drivers.

The TCQ support in atari_NCR5380.c is abandoned by this patch. It is not
merged into the remaining core driver because,

1) atari_scsi defines SUPPORT_TAGS but leaves FLAG_TAGGED_QUEUING disabled
by default, which indicates that it is mostly undesirable.

2) I'm told that it doesn't work correctly when enabled.

3) The algorithm does not make use of block layer tags which it will have
to do because scmd->tag is deprecated.

4) sun3_scsi doesn't define SUPPORT_TAGS at all, yet the the SUPPORT_TAGS
macro interacts with the CONFIG_SUN3 macro in 'interesting' ways.

5) Compile-time configuration with macros like SUPPORT_TAGS caused the
configuration space to explode, leading to untestable and unmaintainable
code that is too hard to reason about.

The merge_contiguous_buffers() code is also abandoned. This was unused
by sun3_scsi. Only atari_scsi used it and then only on TT, because only TT
supports scatter/gather. I suspect that the TT would work fine with
ENABLE_CLUSTERING instead. If someone can benchmark the difference then
perhaps the merge_contiguous_buffers() code can be be justified. Until
then we are better off without the extra complexity.

Signed-off-by: Finn Thain <fthain@telegraphics.com.au>
Reviewed-by: Hannes Reinecke <hare@suse.com>
Tested-by: Michael Schmitz <schmitzmic@gmail.com>
Tested-by: Ondrej Zary <linux@rainbow-software.org>

---
 drivers/scsi/NCR5380.c       |   22 
 drivers/scsi/NCR5380.h       |   19 
 drivers/scsi/atari_NCR5380.c | 2632 -------------------------------------------
 drivers/scsi/atari_scsi.c    |   11 
 drivers/scsi/mac_scsi.c      |    8 
 drivers/scsi/sun3_scsi.c     |   11 
 6 files changed, 4 insertions(+), 2699 deletions(-)

Index: linux/drivers/scsi/atari_scsi.c
===================================================================
--- linux.orig/drivers/scsi/atari_scsi.c	2016-03-23 21:09:51.000000000 +1100
+++ linux/drivers/scsi/atari_scsi.c	2016-03-23 21:09:53.000000000 +1100
@@ -87,9 +87,6 @@
 
 /* Definitions for the core NCR5380 driver. */
 
-#define SUPPORT_TAGS
-#define MAX_TAGS                        32
-
 #define NCR5380_implementation_fields   /* none */
 
 #define NCR5380_read(reg)               atari_scsi_reg_read(reg)
@@ -189,8 +186,6 @@ static int setup_cmd_per_lun = -1;
 module_param(setup_cmd_per_lun, int, 0);
 static int setup_sg_tablesize = -1;
 module_param(setup_sg_tablesize, int, 0);
-static int setup_use_tagged_queuing = -1;
-module_param(setup_use_tagged_queuing, int, 0);
 static int setup_hostid = -1;
 module_param(setup_hostid, int, 0);
 static int setup_toshiba_delay = -1;
@@ -479,8 +474,7 @@ static int __init atari_scsi_setup(char
 		setup_sg_tablesize = ints[3];
 	if (ints[0] >= 4)
 		setup_hostid = ints[4];
-	if (ints[0] >= 5)
-		setup_use_tagged_queuing = ints[5];
+	/* ints[5] (use_tagged_queuing) is ignored */
 	/* ints[6] (use_pdma) is ignored */
 	if (ints[0] >= 7)
 		setup_toshiba_delay = ints[7];
@@ -853,9 +847,6 @@ static int __init atari_scsi_probe(struc
 	instance->irq = irq->start;
 
 	host_flags |= IS_A_TT() ? 0 : FLAG_LATE_DMA_SETUP;
-#ifdef SUPPORT_TAGS
-	host_flags |= setup_use_tagged_queuing > 0 ? FLAG_TAGGED_QUEUING : 0;
-#endif
 	host_flags |= setup_toshiba_delay > 0 ? FLAG_TOSHIBA_DELAY : 0;
 
 	error = NCR5380_init(instance, host_flags);
Index: linux/drivers/scsi/sun3_scsi.c
===================================================================
--- linux.orig/drivers/scsi/sun3_scsi.c	2016-03-23 21:09:52.000000000 +1100
+++ linux/drivers/scsi/sun3_scsi.c	2016-03-23 21:09:53.000000000 +1100
@@ -41,9 +41,6 @@
 
 /* Definitions for the core NCR5380 driver. */
 
-/* #define SUPPORT_TAGS */
-/* #define MAX_TAGS                     32 */
-
 #define NCR5380_implementation_fields   /* none */
 
 #define NCR5380_read(reg)               sun3scsi_read(reg)
@@ -75,10 +72,6 @@ static int setup_cmd_per_lun = -1;
 module_param(setup_cmd_per_lun, int, 0);
 static int setup_sg_tablesize = -1;
 module_param(setup_sg_tablesize, int, 0);
-#ifdef SUPPORT_TAGS
-static int setup_use_tagged_queuing = -1;
-module_param(setup_use_tagged_queuing, int, 0);
-#endif
 static int setup_hostid = -1;
 module_param(setup_hostid, int, 0);
 
@@ -512,10 +505,6 @@ static int __init sun3_scsi_probe(struct
 	instance->io_port = (unsigned long)ioaddr;
 	instance->irq = irq->start;
 
-#ifdef SUPPORT_TAGS
-	host_flags |= setup_use_tagged_queuing > 0 ? FLAG_TAGGED_QUEUING : 0;
-#endif
-
 	error = NCR5380_init(instance, host_flags);
 	if (error)
 		goto fail_init;
Index: linux/drivers/scsi/mac_scsi.c
===================================================================
--- linux.orig/drivers/scsi/mac_scsi.c	2016-03-23 21:09:47.000000000 +1100
+++ linux/drivers/scsi/mac_scsi.c	2016-03-23 21:09:53.000000000 +1100
@@ -55,8 +55,6 @@ static int setup_sg_tablesize = -1;
 module_param(setup_sg_tablesize, int, 0);
 static int setup_use_pdma = -1;
 module_param(setup_use_pdma, int, 0);
-static int setup_use_tagged_queuing = -1;
-module_param(setup_use_tagged_queuing, int, 0);
 static int setup_hostid = -1;
 module_param(setup_hostid, int, 0);
 static int setup_toshiba_delay = -1;
@@ -95,8 +93,7 @@ static int __init mac_scsi_setup(char *s
 		setup_sg_tablesize = ints[3];
 	if (ints[0] >= 4)
 		setup_hostid = ints[4];
-	if (ints[0] >= 5)
-		setup_use_tagged_queuing = ints[5];
+	/* ints[5] (use_tagged_queuing) is ignored */
 	if (ints[0] >= 6)
 		setup_use_pdma = ints[6];
 	if (ints[0] >= 7)
@@ -382,9 +379,6 @@ static int __init mac_scsi_probe(struct
 	} else
 		host_flags |= FLAG_NO_PSEUDO_DMA;
 
-#ifdef SUPPORT_TAGS
-	host_flags |= setup_use_tagged_queuing > 0 ? FLAG_TAGGED_QUEUING : 0;
-#endif
 	host_flags |= setup_toshiba_delay > 0 ? FLAG_TOSHIBA_DELAY : 0;
 
 	error = NCR5380_init(instance, host_flags | FLAG_LATE_DMA_SETUP);
Index: linux/drivers/scsi/NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/NCR5380.c	2016-03-23 21:09:52.000000000 +1100
+++ linux/drivers/scsi/NCR5380.c	2016-03-23 21:09:53.000000000 +1100
@@ -34,13 +34,6 @@
 /* Adapted for the Sun 3 by Sam Creasey. */
 
 /*
- * Further development / testing that should be done :
- *
- * 4.  Test SCSI-II tagged queueing (I have no devices which support
- * tagged queueing)
- */
-
-/*
  * Design
  *
  * This is a generic 5380 driver.  To use it on a different platform,
@@ -1257,14 +1250,6 @@ static struct scsi_cmnd *NCR5380_select(
 	 * was true but before BSY was false during selection, the information
 	 * transfer phase should be a MESSAGE OUT phase so that we can send the
 	 * IDENTIFY message.
-	 *
-	 * If SCSI-II tagged queuing is enabled, we also send a SIMPLE_QUEUE_TAG
-	 * message (2 bytes) with a tag ID that we increment with every command
-	 * until it wraps back to 0.
-	 *
-	 * XXX - it turns out that there are some broken SCSI-II devices,
-	 * which claim to support tagged queuing but fail when more than
-	 * some number of commands are issued at once.
 	 */
 
 	/* Wait for start of REQ/ACK handshake */
@@ -1287,9 +1272,6 @@ static struct scsi_cmnd *NCR5380_select(
 	tmp[0] = IDENTIFY(((instance->irq == NO_IRQ) ? 0 : 1), cmd->device->lun);
 
 	len = 1;
-	cmd->tag = 0;
-
-	/* Send message(s) */
 	data = tmp;
 	phase = PHASE_MSGOUT;
 	NCR5380_transfer_pio(instance, &phase, &len, &data);
@@ -2256,8 +2238,8 @@ static void NCR5380_reselect(struct Scsi
 	NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
 
 	hostdata->connected = tmp;
-	dsprintk(NDEBUG_RESELECTION, instance, "nexus established, target %d, lun %llu, tag %d\n",
-	         scmd_id(tmp), tmp->device->lun, tmp->tag);
+	dsprintk(NDEBUG_RESELECTION, instance, "nexus established, target %d, lun %llu\n",
+	         scmd_id(tmp), tmp->device->lun);
 }
 
 /**
Index: linux/drivers/scsi/NCR5380.h
===================================================================
--- linux.orig/drivers/scsi/NCR5380.h	2016-03-23 21:09:28.000000000 +1100
+++ linux/drivers/scsi/NCR5380.h	2016-03-23 21:09:53.000000000 +1100
@@ -199,13 +199,6 @@
 
 #define PHASE_SR_TO_TCR(phase) ((phase) >> 2)
 
-/* 
- * "Special" value for the (unsigned char) command tag, to indicate
- * I_T_L nexus instead of I_T_L_Q.
- */
-
-#define TAG_NONE	0xff
-
 /*
  * These are "special" values for the irq and dma_channel fields of the 
  * Scsi_Host structure
@@ -223,17 +216,8 @@
 #define FLAG_DMA_FIXUP			1	/* Use DMA errata workarounds */
 #define FLAG_NO_PSEUDO_DMA		8	/* Inhibit DMA */
 #define FLAG_LATE_DMA_SETUP		32	/* Setup NCR before DMA H/W */
-#define FLAG_TAGGED_QUEUING		64	/* as X3T9.2 spelled it */
 #define FLAG_TOSHIBA_DELAY		128	/* Allow for borken CD-ROMs */
 
-#ifdef SUPPORT_TAGS
-struct tag_alloc {
-	DECLARE_BITMAP(allocated, MAX_TAGS);
-	int nr_allocated;
-	int queue_size;
-};
-#endif
-
 struct NCR5380_hostdata {
 	NCR5380_implementation_fields;		/* implementation specific */
 	struct Scsi_Host *host;			/* Host backpointer */
@@ -254,9 +238,6 @@ struct NCR5380_hostdata {
 	int read_overruns;                /* number of bytes to cut from a
 	                                   * transfer to handle chip overruns */
 	struct work_struct main_task;
-#ifdef SUPPORT_TAGS
-	struct tag_alloc TagAlloc[8][8];	/* 8 targets and 8 LUNs */
-#endif
 	struct workqueue_struct *work_q;
 	unsigned long accesses_per_ms;	/* chip register accesses per ms */
 };
Index: linux/drivers/scsi/atari_NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/atari_NCR5380.c	2016-03-23 21:09:24.000000000 +1100
+++ /dev/null	1970-01-01 00:00:00.000000000 +0000
@@ -1,2632 +0,0 @@
-/*
- * NCR 5380 generic driver routines.  These should make it *trivial*
- * to implement 5380 SCSI drivers under Linux with a non-trantor
- * architecture.
- *
- * Note that these routines also work with NR53c400 family chips.
- *
- * Copyright 1993, Drew Eckhardt
- * Visionary Computing
- * (Unix and Linux consulting and custom programming)
- * drew@colorado.edu
- * +1 (303) 666-5836
- *
- * For more information, please consult
- *
- * NCR 5380 Family
- * SCSI Protocol Controller
- * Databook
- *
- * NCR Microelectronics
- * 1635 Aeroplaza Drive
- * Colorado Springs, CO 80916
- * 1+ (719) 578-3400
- * 1+ (800) 334-5454
- */
-
-/* Ported to Atari by Roman Hodek and others. */
-
-/* Adapted for the sun3 by Sam Creasey. */
-
-/*
- * Design
- *
- * This is a generic 5380 driver.  To use it on a different platform,
- * one simply writes appropriate system specific macros (ie, data
- * transfer - some PC's will use the I/O bus, 68K's must use
- * memory mapped) and drops this file in their 'C' wrapper.
- *
- * As far as command queueing, two queues are maintained for
- * each 5380 in the system - commands that haven't been issued yet,
- * and commands that are currently executing.  This means that an
- * unlimited number of commands may be queued, letting
- * more commands propagate from the higher driver levels giving higher
- * throughput.  Note that both I_T_L and I_T_L_Q nexuses are supported,
- * allowing multiple commands to propagate all the way to a SCSI-II device
- * while a command is already executing.
- *
- *
- * Issues specific to the NCR5380 :
- *
- * When used in a PIO or pseudo-dma mode, the NCR5380 is a braindead
- * piece of hardware that requires you to sit in a loop polling for
- * the REQ signal as long as you are connected.  Some devices are
- * brain dead (ie, many TEXEL CD ROM drives) and won't disconnect
- * while doing long seek operations. [...] These
- * broken devices are the exception rather than the rule and I'd rather
- * spend my time optimizing for the normal case.
- *
- * Architecture :
- *
- * At the heart of the design is a coroutine, NCR5380_main,
- * which is started from a workqueue for each NCR5380 host in the
- * system.  It attempts to establish I_T_L or I_T_L_Q nexuses by
- * removing the commands from the issue queue and calling
- * NCR5380_select() if a nexus is not established.
- *
- * Once a nexus is established, the NCR5380_information_transfer()
- * phase goes through the various phases as instructed by the target.
- * if the target goes into MSG IN and sends a DISCONNECT message,
- * the command structure is placed into the per instance disconnected
- * queue, and NCR5380_main tries to find more work.  If the target is
- * idle for too long, the system will try to sleep.
- *
- * If a command has disconnected, eventually an interrupt will trigger,
- * calling NCR5380_intr()  which will in turn call NCR5380_reselect
- * to reestablish a nexus.  This will run main if necessary.
- *
- * On command termination, the done function will be called as
- * appropriate.
- *
- * SCSI pointers are maintained in the SCp field of SCSI command
- * structures, being initialized after the command is connected
- * in NCR5380_select, and set as appropriate in NCR5380_information_transfer.
- * Note that in violation of the standard, an implicit SAVE POINTERS operation
- * is done, since some BROKEN disks fail to issue an explicit SAVE POINTERS.
- */
-
-/*
- * Using this file :
- * This file a skeleton Linux SCSI driver for the NCR 5380 series
- * of chips.  To use it, you write an architecture specific functions
- * and macros and include this file in your driver.
- *
- * These macros control options :
- * AUTOSENSE - if defined, REQUEST SENSE will be performed automatically
- * for commands that return with a CHECK CONDITION status.
- *
- * DIFFERENTIAL - if defined, NCR53c81 chips will use external differential
- * transceivers.
- *
- * REAL_DMA - if defined, REAL DMA is used during the data transfer phases.
- *
- * SUPPORT_TAGS - if defined, SCSI-2 tagged queuing is used where possible
- *
- * These macros MUST be defined :
- *
- * NCR5380_read(register)  - read from the specified register
- *
- * NCR5380_write(register, value) - write to the specific register
- *
- * NCR5380_implementation_fields  - additional fields needed for this
- * specific implementation of the NCR5380
- *
- * Either real DMA *or* pseudo DMA may be implemented
- * Note that the DMA setup functions should return the number of bytes
- * that they were able to program the controller for.
- *
- * NCR5380_dma_write_setup(instance, src, count) - initialize
- * NCR5380_dma_read_setup(instance, dst, count) - initialize
- * NCR5380_dma_residual(instance); - residual count
- *
- * PSEUDO functions :
- * NCR5380_pwrite(instance, src, count)
- * NCR5380_pread(instance, dst, count);
- *
- * The generic driver is initialized by calling NCR5380_init(instance),
- * after setting the appropriate host specific fields and ID.  If the
- * driver wishes to autoprobe for an IRQ line, the NCR5380_probe_irq(instance,
- * possible) function may be used.
- */
-
-static int do_abort(struct Scsi_Host *);
-static void do_reset(struct Scsi_Host *);
-
-#ifdef SUPPORT_TAGS
-
-/*
- * Functions for handling tagged queuing
- * =====================================
- *
- * ++roman (01/96): Now I've implemented SCSI-2 tagged queuing. Some notes:
- *
- * Using consecutive numbers for the tags is no good idea in my eyes. There
- * could be wrong re-usings if the counter (8 bit!) wraps and some early
- * command has been preempted for a long time. My solution: a bitfield for
- * remembering used tags.
- *
- * There's also the problem that each target has a certain queue size, but we
- * cannot know it in advance :-( We just see a QUEUE_FULL status being
- * returned. So, in this case, the driver internal queue size assumption is
- * reduced to the number of active tags if QUEUE_FULL is returned by the
- * target.
- *
- * We're also not allowed running tagged commands as long as an untagged
- * command is active. And REQUEST SENSE commands after a contingent allegiance
- * condition _must_ be untagged. To keep track whether an untagged command has
- * been issued, the host->busy array is still employed, as it is without
- * support for tagged queuing.
- *
- * One could suspect that there are possible race conditions between
- * is_lun_busy(), cmd_get_tag() and cmd_free_tag(). But I think this isn't the
- * case: is_lun_busy() and cmd_get_tag() are both called from NCR5380_main(),
- * which already guaranteed to be running at most once. It is also the only
- * place where tags/LUNs are allocated. So no other allocation can slip
- * between that pair, there could only happen a reselection, which can free a
- * tag, but that doesn't hurt. Only the sequence in cmd_free_tag() becomes
- * important: the tag bit must be cleared before 'nr_allocated' is decreased.
- */
-
-static void __init init_tags(struct NCR5380_hostdata *hostdata)
-{
-	int target, lun;
-	struct tag_alloc *ta;
-
-	if (!(hostdata->flags & FLAG_TAGGED_QUEUING))
-		return;
-
-	for (target = 0; target < 8; ++target) {
-		for (lun = 0; lun < 8; ++lun) {
-			ta = &hostdata->TagAlloc[target][lun];
-			bitmap_zero(ta->allocated, MAX_TAGS);
-			ta->nr_allocated = 0;
-			/* At the beginning, assume the maximum queue size we could
-			 * support (MAX_TAGS). This value will be decreased if the target
-			 * returns QUEUE_FULL status.
-			 */
-			ta->queue_size = MAX_TAGS;
-		}
-	}
-}
-
-
-/* Check if we can issue a command to this LUN: First see if the LUN is marked
- * busy by an untagged command. If the command should use tagged queuing, also
- * check that there is a free tag and the target's queue won't overflow. This
- * function should be called with interrupts disabled to avoid race
- * conditions.
- */
-
-static int is_lun_busy(struct scsi_cmnd *cmd, int should_be_tagged)
-{
-	u8 lun = cmd->device->lun;
-	struct Scsi_Host *instance = cmd->device->host;
-	struct NCR5380_hostdata *hostdata = shost_priv(instance);
-
-	if (hostdata->busy[cmd->device->id] & (1 << lun))
-		return 1;
-	if (!should_be_tagged ||
-	    !(hostdata->flags & FLAG_TAGGED_QUEUING) ||
-	    !cmd->device->tagged_supported)
-		return 0;
-	if (hostdata->TagAlloc[scmd_id(cmd)][lun].nr_allocated >=
-	    hostdata->TagAlloc[scmd_id(cmd)][lun].queue_size) {
-		dsprintk(NDEBUG_TAGS, instance, "target %d lun %d: no free tags\n",
-		         scmd_id(cmd), lun);
-		return 1;
-	}
-	return 0;
-}
-
-
-/* Allocate a tag for a command (there are no checks anymore, check_lun_busy()
- * must be called before!), or reserve the LUN in 'busy' if the command is
- * untagged.
- */
-
-static void cmd_get_tag(struct scsi_cmnd *cmd, int should_be_tagged)
-{
-	u8 lun = cmd->device->lun;
-	struct Scsi_Host *instance = cmd->device->host;
-	struct NCR5380_hostdata *hostdata = shost_priv(instance);
-
-	/* If we or the target don't support tagged queuing, allocate the LUN for
-	 * an untagged command.
-	 */
-	if (!should_be_tagged ||
-	    !(hostdata->flags & FLAG_TAGGED_QUEUING) ||
-	    !cmd->device->tagged_supported) {
-		cmd->tag = TAG_NONE;
-		hostdata->busy[cmd->device->id] |= (1 << lun);
-		dsprintk(NDEBUG_TAGS, instance, "target %d lun %d now allocated by untagged command\n",
-		         scmd_id(cmd), lun);
-	} else {
-		struct tag_alloc *ta = &hostdata->TagAlloc[scmd_id(cmd)][lun];
-
-		cmd->tag = find_first_zero_bit(ta->allocated, MAX_TAGS);
-		set_bit(cmd->tag, ta->allocated);
-		ta->nr_allocated++;
-		dsprintk(NDEBUG_TAGS, instance, "using tag %d for target %d lun %d (%d tags allocated)\n",
-		         cmd->tag, scmd_id(cmd), lun, ta->nr_allocated);
-	}
-}
-
-
-/* Mark the tag of command 'cmd' as free, or in case of an untagged command,
- * unlock the LUN.
- */
-
-static void cmd_free_tag(struct scsi_cmnd *cmd)
-{
-	u8 lun = cmd->device->lun;
-	struct Scsi_Host *instance = cmd->device->host;
-	struct NCR5380_hostdata *hostdata = shost_priv(instance);
-
-	if (cmd->tag == TAG_NONE) {
-		hostdata->busy[cmd->device->id] &= ~(1 << lun);
-		dsprintk(NDEBUG_TAGS, instance, "target %d lun %d untagged cmd freed\n",
-		         scmd_id(cmd), lun);
-	} else if (cmd->tag >= MAX_TAGS) {
-		shost_printk(KERN_NOTICE, instance,
-		             "trying to free bad tag %d!\n", cmd->tag);
-	} else {
-		struct tag_alloc *ta = &hostdata->TagAlloc[scmd_id(cmd)][lun];
-		clear_bit(cmd->tag, ta->allocated);
-		ta->nr_allocated--;
-		dsprintk(NDEBUG_TAGS, instance, "freed tag %d for target %d lun %d\n",
-		         cmd->tag, scmd_id(cmd), lun);
-	}
-}
-
-
-static void free_all_tags(struct NCR5380_hostdata *hostdata)
-{
-	int target, lun;
-	struct tag_alloc *ta;
-
-	if (!(hostdata->flags & FLAG_TAGGED_QUEUING))
-		return;
-
-	for (target = 0; target < 8; ++target) {
-		for (lun = 0; lun < 8; ++lun) {
-			ta = &hostdata->TagAlloc[target][lun];
-			bitmap_zero(ta->allocated, MAX_TAGS);
-			ta->nr_allocated = 0;
-		}
-	}
-}
-
-#endif /* SUPPORT_TAGS */
-
-/**
- * merge_contiguous_buffers - coalesce scatter-gather list entries
- * @cmd: command requesting IO
- *
- * Try to merge several scatter-gather buffers into one DMA transfer.
- * This is possible if the scatter buffers lie on physically
- * contiguous addresses. The first scatter-gather buffer's data are
- * assumed to be already transferred into cmd->SCp.this_residual.
- * Every buffer merged avoids an interrupt and a DMA setup operation.
- */
-
-static void merge_contiguous_buffers(struct scsi_cmnd *cmd)
-{
-#if !defined(CONFIG_SUN3)
-	unsigned long endaddr;
-#if (NDEBUG & NDEBUG_MERGING)
-	unsigned long oldlen = cmd->SCp.this_residual;
-	int cnt = 1;
-#endif
-
-	for (endaddr = virt_to_phys(cmd->SCp.ptr + cmd->SCp.this_residual - 1) + 1;
-	     cmd->SCp.buffers_residual &&
-	     virt_to_phys(sg_virt(&cmd->SCp.buffer[1])) == endaddr;) {
-		dprintk(NDEBUG_MERGING, "VTOP(%p) == %08lx -> merging\n",
-			   page_address(sg_page(&cmd->SCp.buffer[1])), endaddr);
-#if (NDEBUG & NDEBUG_MERGING)
-		++cnt;
-#endif
-		++cmd->SCp.buffer;
-		--cmd->SCp.buffers_residual;
-		cmd->SCp.this_residual += cmd->SCp.buffer->length;
-		endaddr += cmd->SCp.buffer->length;
-	}
-#if (NDEBUG & NDEBUG_MERGING)
-	if (oldlen != cmd->SCp.this_residual)
-		dprintk(NDEBUG_MERGING, "merged %d buffers from %p, new length %08x\n",
-			   cnt, cmd->SCp.ptr, cmd->SCp.this_residual);
-#endif
-#endif /* !defined(CONFIG_SUN3) */
-}
-
-/**
- * initialize_SCp - init the scsi pointer field
- * @cmd: command block to set up
- *
- * Set up the internal fields in the SCSI command.
- */
-
-static inline void initialize_SCp(struct scsi_cmnd *cmd)
-{
-	/*
-	 * Initialize the Scsi Pointer field so that all of the commands in the
-	 * various queues are valid.
-	 */
-
-	if (scsi_bufflen(cmd)) {
-		cmd->SCp.buffer = scsi_sglist(cmd);
-		cmd->SCp.buffers_residual = scsi_sg_count(cmd) - 1;
-		cmd->SCp.ptr = sg_virt(cmd->SCp.buffer);
-		cmd->SCp.this_residual = cmd->SCp.buffer->length;
-
-		merge_contiguous_buffers(cmd);
-	} else {
-		cmd->SCp.buffer = NULL;
-		cmd->SCp.buffers_residual = 0;
-		cmd->SCp.ptr = NULL;
-		cmd->SCp.this_residual = 0;
-	}
-
-	cmd->SCp.Status = 0;
-	cmd->SCp.Message = 0;
-}
-
-/**
- * NCR5380_poll_politely2 - wait for two chip register values
- * @instance: controller to poll
- * @reg1: 5380 register to poll
- * @bit1: Bitmask to check
- * @val1: Expected value
- * @reg2: Second 5380 register to poll
- * @bit2: Second bitmask to check
- * @val2: Second expected value
- * @wait: Time-out in jiffies
- *
- * Polls the chip in a reasonably efficient manner waiting for an
- * event to occur. After a short quick poll we begin to yield the CPU
- * (if possible). In irq contexts the time-out is arbitrarily limited.
- * Callers may hold locks as long as they are held in irq mode.
- *
- * Returns 0 if either or both event(s) occurred otherwise -ETIMEDOUT.
- */
-
-static int NCR5380_poll_politely2(struct Scsi_Host *instance,
-                                  int reg1, int bit1, int val1,
-                                  int reg2, int bit2, int val2, int wait)
-{
-	struct NCR5380_hostdata *hostdata = shost_priv(instance);
-	unsigned long deadline = jiffies + wait;
-	unsigned long n;
-
-	/* Busy-wait for up to 10 ms */
-	n = min(10000U, jiffies_to_usecs(wait));
-	n *= hostdata->accesses_per_ms;
-	n /= 2000;
-	do {
-		if ((NCR5380_read(reg1) & bit1) == val1)
-			return 0;
-		if ((NCR5380_read(reg2) & bit2) == val2)
-			return 0;
-		cpu_relax();
-	} while (n--);
-
-	if (irqs_disabled() || in_interrupt())
-		return -ETIMEDOUT;
-
-	/* Repeatedly sleep for 1 ms until deadline */
-	while (time_is_after_jiffies(deadline)) {
-		schedule_timeout_uninterruptible(1);
-		if ((NCR5380_read(reg1) & bit1) == val1)
-			return 0;
-		if ((NCR5380_read(reg2) & bit2) == val2)
-			return 0;
-	}
-
-	return -ETIMEDOUT;
-}
-
-static inline int NCR5380_poll_politely(struct Scsi_Host *instance,
-                                        int reg, int bit, int val, int wait)
-{
-	return NCR5380_poll_politely2(instance, reg, bit, val,
-	                                        reg, bit, val, wait);
-}
-
-#if NDEBUG
-static struct {
-	unsigned char mask;
-	const char *name;
-} signals[] = {
-	{SR_DBP, "PARITY"},
-	{SR_RST, "RST"},
-	{SR_BSY, "BSY"},
-	{SR_REQ, "REQ"},
-	{SR_MSG, "MSG"},
-	{SR_CD, "CD"},
-	{SR_IO, "IO"},
-	{SR_SEL, "SEL"},
-	{0, NULL}
-},
-basrs[] = {
-	{BASR_ATN, "ATN"},
-	{BASR_ACK, "ACK"},
-	{0, NULL}
-},
-icrs[] = {
-	{ICR_ASSERT_RST, "ASSERT RST"},
-	{ICR_ASSERT_ACK, "ASSERT ACK"},
-	{ICR_ASSERT_BSY, "ASSERT BSY"},
-	{ICR_ASSERT_SEL, "ASSERT SEL"},
-	{ICR_ASSERT_ATN, "ASSERT ATN"},
-	{ICR_ASSERT_DATA, "ASSERT DATA"},
-	{0, NULL}
-},
-mrs[] = {
-	{MR_BLOCK_DMA_MODE, "MODE BLOCK DMA"},
-	{MR_TARGET, "MODE TARGET"},
-	{MR_ENABLE_PAR_CHECK, "MODE PARITY CHECK"},
-	{MR_ENABLE_PAR_INTR, "MODE PARITY INTR"},
-	{MR_ENABLE_EOP_INTR, "MODE EOP INTR"},
-	{MR_MONITOR_BSY, "MODE MONITOR BSY"},
-	{MR_DMA_MODE, "MODE DMA"},
-	{MR_ARBITRATE, "MODE ARBITRATION"},
-	{0, NULL}
-};
-
-/**
- * NCR5380_print - print scsi bus signals
- * @instance: adapter state to dump
- *
- * Print the SCSI bus signals for debugging purposes
- */
-
-static void NCR5380_print(struct Scsi_Host *instance)
-{
-	unsigned char status, data, basr, mr, icr, i;
-
-	data = NCR5380_read(CURRENT_SCSI_DATA_REG);
-	status = NCR5380_read(STATUS_REG);
-	mr = NCR5380_read(MODE_REG);
-	icr = NCR5380_read(INITIATOR_COMMAND_REG);
-	basr = NCR5380_read(BUS_AND_STATUS_REG);
-
-	printk("STATUS_REG: %02x ", status);
-	for (i = 0; signals[i].mask; ++i)
-		if (status & signals[i].mask)
-			printk(",%s", signals[i].name);
-	printk("\nBASR: %02x ", basr);
-	for (i = 0; basrs[i].mask; ++i)
-		if (basr & basrs[i].mask)
-			printk(",%s", basrs[i].name);
-	printk("\nICR: %02x ", icr);
-	for (i = 0; icrs[i].mask; ++i)
-		if (icr & icrs[i].mask)
-			printk(",%s", icrs[i].name);
-	printk("\nMODE: %02x ", mr);
-	for (i = 0; mrs[i].mask; ++i)
-		if (mr & mrs[i].mask)
-			printk(",%s", mrs[i].name);
-	printk("\n");
-}
-
-static struct {
-	unsigned char value;
-	const char *name;
-} phases[] = {
-	{PHASE_DATAOUT, "DATAOUT"},
-	{PHASE_DATAIN, "DATAIN"},
-	{PHASE_CMDOUT, "CMDOUT"},
-	{PHASE_STATIN, "STATIN"},
-	{PHASE_MSGOUT, "MSGOUT"},
-	{PHASE_MSGIN, "MSGIN"},
-	{PHASE_UNKNOWN, "UNKNOWN"}
-};
-
-/**
- * NCR5380_print_phase - show SCSI phase
- * @instance: adapter to dump
- *
- * Print the current SCSI phase for debugging purposes
- */
-
-static void NCR5380_print_phase(struct Scsi_Host *instance)
-{
-	unsigned char status;
-	int i;
-
-	status = NCR5380_read(STATUS_REG);
-	if (!(status & SR_REQ))
-		shost_printk(KERN_DEBUG, instance, "REQ not asserted, phase unknown.\n");
-	else {
-		for (i = 0; (phases[i].value != PHASE_UNKNOWN) &&
-		     (phases[i].value != (status & PHASE_MASK)); ++i)
-			;
-		shost_printk(KERN_DEBUG, instance, "phase %s\n", phases[i].name);
-	}
-}
-#endif
-
-/**
- * NCR58380_info - report driver and host information
- * @instance: relevant scsi host instance
- *
- * For use as the host template info() handler.
- */
-
-static const char *NCR5380_info(struct Scsi_Host *instance)
-{
-	struct NCR5380_hostdata *hostdata = shost_priv(instance);
-
-	return hostdata->info;
-}
-
-static void prepare_info(struct Scsi_Host *instance)
-{
-	struct NCR5380_hostdata *hostdata = shost_priv(instance);
-
-	snprintf(hostdata->info, sizeof(hostdata->info),
-	         "%s, io_port 0x%lx, n_io_port %d, "
-	         "base 0x%lx, irq %d, "
-	         "can_queue %d, cmd_per_lun %d, "
-	         "sg_tablesize %d, this_id %d, "
-	         "flags { %s%s}, "
-	         "options { %s} ",
-	         instance->hostt->name, instance->io_port, instance->n_io_port,
-	         instance->base, instance->irq,
-	         instance->can_queue, instance->cmd_per_lun,
-	         instance->sg_tablesize, instance->this_id,
-	         hostdata->flags & FLAG_TAGGED_QUEUING ? "TAGGED_QUEUING " : "",
-	         hostdata->flags & FLAG_TOSHIBA_DELAY  ? "TOSHIBA_DELAY "  : "",
-#ifdef DIFFERENTIAL
-	         "DIFFERENTIAL "
-#endif
-#ifdef PARITY
-	         "PARITY "
-#endif
-#ifdef SUPPORT_TAGS
-	         "SUPPORT_TAGS "
-#endif
-	         "");
-}
-
-/**
- * NCR5380_init - initialise an NCR5380
- * @instance: adapter to configure
- * @flags: control flags
- *
- * Initializes *instance and corresponding 5380 chip,
- * with flags OR'd into the initial flags value.
- *
- * Notes : I assume that the host, hostno, and id bits have been
- * set correctly. I don't care about the irq and other fields.
- *
- * Returns 0 for success
- */
-
-static int __init NCR5380_init(struct Scsi_Host *instance, int flags)
-{
-	struct NCR5380_hostdata *hostdata = shost_priv(instance);
-	int i;
-	unsigned long deadline;
-
-	hostdata->host = instance;
-	hostdata->id_mask = 1 << instance->this_id;
-	hostdata->id_higher_mask = 0;
-	for (i = hostdata->id_mask; i <= 0x80; i <<= 1)
-		if (i > hostdata->id_mask)
-			hostdata->id_higher_mask |= i;
-	for (i = 0; i < 8; ++i)
-		hostdata->busy[i] = 0;
-#ifdef SUPPORT_TAGS
-	init_tags(hostdata);
-#endif
-	hostdata->dma_len = 0;
-
-	spin_lock_init(&hostdata->lock);
-	hostdata->connected = NULL;
-	hostdata->sensing = NULL;
-	INIT_LIST_HEAD(&hostdata->autosense);
-	INIT_LIST_HEAD(&hostdata->unissued);
-	INIT_LIST_HEAD(&hostdata->disconnected);
-
-	hostdata->flags = flags;
-
-	INIT_WORK(&hostdata->main_task, NCR5380_main);
-	hostdata->work_q = alloc_workqueue("ncr5380_%d",
-	                        WQ_UNBOUND | WQ_MEM_RECLAIM,
-	                        1, instance->host_no);
-	if (!hostdata->work_q)
-		return -ENOMEM;
-
-	prepare_info(instance);
-
-	NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
-	NCR5380_write(MODE_REG, MR_BASE);
-	NCR5380_write(TARGET_COMMAND_REG, 0);
-	NCR5380_write(SELECT_ENABLE_REG, 0);
-
-	/* Calibrate register polling loop */
-	i = 0;
-	deadline = jiffies + 1;
-	do {
-		cpu_relax();
-	} while (time_is_after_jiffies(deadline));
-	deadline += msecs_to_jiffies(256);
-	do {
-		NCR5380_read(STATUS_REG);
-		++i;
-		cpu_relax();
-	} while (time_is_after_jiffies(deadline));
-	hostdata->accesses_per_ms = i / 256;
-
-	return 0;
-}
-
-/**
- * NCR5380_maybe_reset_bus - Detect and correct bus wedge problems.
- * @instance: adapter to check
- *
- * If the system crashed, it may have crashed with a connected target and
- * the SCSI bus busy. Check for BUS FREE phase. If not, try to abort the
- * currently established nexus, which we know nothing about. Failing that
- * do a bus reset.
- *
- * Note that a bus reset will cause the chip to assert IRQ.
- *
- * Returns 0 if successful, otherwise -ENXIO.
- */
-
-static int NCR5380_maybe_reset_bus(struct Scsi_Host *instance)
-{
-	struct NCR5380_hostdata *hostdata = shost_priv(instance);
-	int pass;
-
-	for (pass = 1; (NCR5380_read(STATUS_REG) & SR_BSY) && pass <= 6; ++pass) {
-		switch (pass) {
-		case 1:
-		case 3:
-		case 5:
-			shost_printk(KERN_ERR, instance, "SCSI bus busy, waiting up to five seconds\n");
-			NCR5380_poll_politely(instance,
-			                      STATUS_REG, SR_BSY, 0, 5 * HZ);
-			break;
-		case 2:
-			shost_printk(KERN_ERR, instance, "bus busy, attempting abort\n");
-			do_abort(instance);
-			break;
-		case 4:
-			shost_printk(KERN_ERR, instance, "bus busy, attempting reset\n");
-			do_reset(instance);
-			/* Wait after a reset; the SCSI standard calls for
-			 * 250ms, we wait 500ms to be on the safe side.
-			 * But some Toshiba CD-ROMs need ten times that.
-			 */
-			if (hostdata->flags & FLAG_TOSHIBA_DELAY)
-				msleep(2500);
-			else
-				msleep(500);
-			break;
-		case 6:
-			shost_printk(KERN_ERR, instance, "bus locked solid\n");
-			return -ENXIO;
-		}
-	}
-	return 0;
-}
-
-/**
- * NCR5380_exit - remove an NCR5380
- * @instance: adapter to remove
- *
- * Assumes that no more work can be queued (e.g. by NCR5380_intr).
- */
-
-static void NCR5380_exit(struct Scsi_Host *instance)
-{
-	struct NCR5380_hostdata *hostdata = shost_priv(instance);
-
-	cancel_work_sync(&hostdata->main_task);
-	destroy_workqueue(hostdata->work_q);
-}
-
-/**
- * complete_cmd - finish processing a command and return it to the SCSI ML
- * @instance: the host instance
- * @cmd: command to complete
- */
-
-static void complete_cmd(struct Scsi_Host *instance,
-                         struct scsi_cmnd *cmd)
-{
-	struct NCR5380_hostdata *hostdata = shost_priv(instance);
-
-	dsprintk(NDEBUG_QUEUES, instance, "complete_cmd: cmd %p\n", cmd);
-
-	if (hostdata->sensing == cmd) {
-		/* Autosense processing ends here */
-		if ((cmd->result & 0xff) != SAM_STAT_GOOD) {
-			scsi_eh_restore_cmnd(cmd, &hostdata->ses);
-			set_host_byte(cmd, DID_ERROR);
-		} else
-			scsi_eh_restore_cmnd(cmd, &hostdata->ses);
-		hostdata->sensing = NULL;
-	}
-
-#ifdef SUPPORT_TAGS
-	cmd_free_tag(cmd);
-#else
-	hostdata->busy[scmd_id(cmd)] &= ~(1 << cmd->device->lun);
-#endif
-	cmd->scsi_done(cmd);
-}
-
-/**
- * NCR5380_queue_command - queue a command
- * @instance: the relevant SCSI adapter
- * @cmd: SCSI command
- *
- * cmd is added to the per-instance issue queue, with minor
- * twiddling done to the host specific fields of cmd.  If the
- * main coroutine is not running, it is restarted.
- */
-
-static int NCR5380_queue_command(struct Scsi_Host *instance,
-                                 struct scsi_cmnd *cmd)
-{
-	struct NCR5380_hostdata *hostdata = shost_priv(instance);
-	struct NCR5380_cmd *ncmd = scsi_cmd_priv(cmd);
-	unsigned long flags;
-
-#if (NDEBUG & NDEBUG_NO_WRITE)
-	switch (cmd->cmnd[0]) {
-	case WRITE_6:
-	case WRITE_10:
-		shost_printk(KERN_DEBUG, instance, "WRITE attempted with NDEBUG_NO_WRITE set\n");
-		cmd->result = (DID_ERROR << 16);
-		cmd->scsi_done(cmd);
-		return 0;
-	}
-#endif /* (NDEBUG & NDEBUG_NO_WRITE) */
-
-	cmd->result = 0;
-
-	/*
-	 * ++roman: Just disabling the NCR interrupt isn't sufficient here,
-	 * because also a timer int can trigger an abort or reset, which would
-	 * alter queues and touch the lock.
-	 */
-	if (!NCR5380_acquire_dma_irq(instance))
-		return SCSI_MLQUEUE_HOST_BUSY;
-
-	spin_lock_irqsave(&hostdata->lock, flags);
-
-	/*
-	 * Insert the cmd into the issue queue. Note that REQUEST SENSE
-	 * commands are added to the head of the queue since any command will
-	 * clear the contingent allegiance condition that exists and the
-	 * sense data is only guaranteed to be valid while the condition exists.
-	 */
-
-	if (cmd->cmnd[0] == REQUEST_SENSE)
-		list_add(&ncmd->list, &hostdata->unissued);
-	else
-		list_add_tail(&ncmd->list, &hostdata->unissued);
-
-	spin_unlock_irqrestore(&hostdata->lock, flags);
-
-	dsprintk(NDEBUG_QUEUES, instance, "command %p added to %s of queue\n",
-	         cmd, (cmd->cmnd[0] == REQUEST_SENSE) ? "head" : "tail");
-
-	/* Kick off command processing */
-	queue_work(hostdata->work_q, &hostdata->main_task);
-	return 0;
-}
-
-static inline void maybe_release_dma_irq(struct Scsi_Host *instance)
-{
-	struct NCR5380_hostdata *hostdata = shost_priv(instance);
-
-	/* Caller does the locking needed to set & test these data atomically */
-	if (list_empty(&hostdata->disconnected) &&
-	    list_empty(&hostdata->unissued) &&
-	    list_empty(&hostdata->autosense) &&
-	    !hostdata->connected &&
-	    !hostdata->selecting)
-		NCR5380_release_dma_irq(instance);
-}
-
-/**
- * dequeue_next_cmd - dequeue a command for processing
- * @instance: the scsi host instance
- *
- * Priority is given to commands on the autosense queue. These commands
- * need autosense because of a CHECK CONDITION result.
- *
- * Returns a command pointer if a command is found for a target that is
- * not already busy. Otherwise returns NULL.
- */
-
-static struct scsi_cmnd *dequeue_next_cmd(struct Scsi_Host *instance)
-{
-	struct NCR5380_hostdata *hostdata = shost_priv(instance);
-	struct NCR5380_cmd *ncmd;
-	struct scsi_cmnd *cmd;
-
-	if (hostdata->sensing || list_empty(&hostdata->autosense)) {
-		list_for_each_entry(ncmd, &hostdata->unissued, list) {
-			cmd = NCR5380_to_scmd(ncmd);
-			dsprintk(NDEBUG_QUEUES, instance, "dequeue: cmd=%p target=%d busy=0x%02x lun=%llu\n",
-			         cmd, scmd_id(cmd), hostdata->busy[scmd_id(cmd)], cmd->device->lun);
-
-			if (
-#ifdef SUPPORT_TAGS
-			    !is_lun_busy(cmd, 1)
-#else
-			    !(hostdata->busy[scmd_id(cmd)] & (1 << cmd->device->lun))
-#endif
-			) {
-				list_del(&ncmd->list);
-				dsprintk(NDEBUG_QUEUES, instance,
-				         "dequeue: removed %p from issue queue\n", cmd);
-				return cmd;
-			}
-		}
-	} else {
-		/* Autosense processing begins here */
-		ncmd = list_first_entry(&hostdata->autosense,
-		                        struct NCR5380_cmd, list);
-		list_del(&ncmd->list);
-		cmd = NCR5380_to_scmd(ncmd);
-		dsprintk(NDEBUG_QUEUES, instance,
-		         "dequeue: removed %p from autosense queue\n", cmd);
-		scsi_eh_prep_cmnd(cmd, &hostdata->ses, NULL, 0, ~0);
-		hostdata->sensing = cmd;
-		return cmd;
-	}
-	return NULL;
-}
-
-static void requeue_cmd(struct Scsi_Host *instance, struct scsi_cmnd *cmd)
-{
-	struct NCR5380_hostdata *hostdata = shost_priv(instance);
-	struct NCR5380_cmd *ncmd = scsi_cmd_priv(cmd);
-
-	if (hostdata->sensing == cmd) {
-		scsi_eh_restore_cmnd(cmd, &hostdata->ses);
-		list_add(&ncmd->list, &hostdata->autosense);
-		hostdata->sensing = NULL;
-	} else
-		list_add(&ncmd->list, &hostdata->unissued);
-}
-
-/**
- * NCR5380_main - NCR state machines
- *
- * NCR5380_main is a coroutine that runs as long as more work can
- * be done on the NCR5380 host adapters in a system.  Both
- * NCR5380_queue_command() and NCR5380_intr() will try to start it
- * in case it is not running.
- */
-
-static void NCR5380_main(struct work_struct *work)
-{
-	struct NCR5380_hostdata *hostdata =
-		container_of(work, struct NCR5380_hostdata, main_task);
-	struct Scsi_Host *instance = hostdata->host;
-	int done;
-
-	/*
-	 * ++roman: Just disabling the NCR interrupt isn't sufficient here,
-	 * because also a timer int can trigger an abort or reset, which can
-	 * alter queues and touch the Falcon lock.
-	 */
-
-	do {
-		done = 1;
-
-		spin_lock_irq(&hostdata->lock);
-		while (!hostdata->connected && !hostdata->selecting) {
-			struct scsi_cmnd *cmd = dequeue_next_cmd(instance);
-
-			if (!cmd)
-				break;
-
-			dsprintk(NDEBUG_MAIN, instance, "main: dequeued %p\n", cmd);
-
-			/*
-			 * Attempt to establish an I_T_L nexus here.
-			 * On success, instance->hostdata->connected is set.
-			 * On failure, we must add the command back to the
-			 * issue queue so we can keep trying.
-			 */
-			/*
-			 * REQUEST SENSE commands are issued without tagged
-			 * queueing, even on SCSI-II devices because the
-			 * contingent allegiance condition exists for the
-			 * entire unit.
-			 */
-			/* ++roman: ...and the standard also requires that
-			 * REQUEST SENSE command are untagged.
-			 */
-
-#ifdef SUPPORT_TAGS
-			cmd_get_tag(cmd, cmd->cmnd[0] != REQUEST_SENSE);
-#endif
-			if (!NCR5380_select(instance, cmd)) {
-				dsprintk(NDEBUG_MAIN, instance, "main: select complete\n");
-				maybe_release_dma_irq(instance);
-			} else {
-				dsprintk(NDEBUG_MAIN | NDEBUG_QUEUES, instance,
-				         "main: select failed, returning %p to queue\n", cmd);
-				requeue_cmd(instance, cmd);
-#ifdef SUPPORT_TAGS
-				cmd_free_tag(cmd);
-#endif
-			}
-		}
-		if (hostdata->connected && !hostdata->dma_len) {
-			dsprintk(NDEBUG_MAIN, instance, "main: performing information transfer\n");
-			NCR5380_information_transfer(instance);
-			done = 0;
-		}
-		spin_unlock_irq(&hostdata->lock);
-		if (!done)
-			cond_resched();
-	} while (!done);
-}
-
-
-/*
- * Function : void NCR5380_dma_complete (struct Scsi_Host *instance)
- *
- * Purpose : Called by interrupt handler when DMA finishes or a phase
- * mismatch occurs (which would finish the DMA transfer).
- *
- * Inputs : instance - this instance of the NCR5380.
- */
-
-static void NCR5380_dma_complete(struct Scsi_Host *instance)
-{
-	struct NCR5380_hostdata *hostdata = shost_priv(instance);
-	int transferred;
-	unsigned char **data;
-	int *count;
-	int saved_data = 0, overrun = 0;
-	unsigned char p;
-
-	if (hostdata->read_overruns) {
-		p = hostdata->connected->SCp.phase;
-		if (p & SR_IO) {
-			udelay(10);
-			if ((NCR5380_read(BUS_AND_STATUS_REG) &
-			     (BASR_PHASE_MATCH|BASR_ACK)) ==
-			    (BASR_PHASE_MATCH|BASR_ACK)) {
-				saved_data = NCR5380_read(INPUT_DATA_REG);
-				overrun = 1;
-				dsprintk(NDEBUG_DMA, instance, "read overrun handled\n");
-			}
-		}
-	}
-
-#if defined(CONFIG_SUN3)
-	if ((sun3scsi_dma_finish(rq_data_dir(hostdata->connected->request)))) {
-		pr_err("scsi%d: overrun in UDC counter -- not prepared to deal with this!\n",
-		       instance->host_no);
-		BUG();
-	}
-
-	/* make sure we're not stuck in a data phase */
-	if ((NCR5380_read(BUS_AND_STATUS_REG) & (BASR_PHASE_MATCH | BASR_ACK)) ==
-	    (BASR_PHASE_MATCH | BASR_ACK)) {
-		pr_err("scsi%d: BASR %02x\n", instance->host_no,
-		       NCR5380_read(BUS_AND_STATUS_REG));
-		pr_err("scsi%d: bus stuck in data phase -- probably a single byte overrun!\n",
-		       instance->host_no);
-		BUG();
-	}
-#endif
-
-	NCR5380_write(MODE_REG, MR_BASE);
-	NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
-	NCR5380_read(RESET_PARITY_INTERRUPT_REG);
-
-	transferred = hostdata->dma_len - NCR5380_dma_residual(instance);
-	hostdata->dma_len = 0;
-
-	data = (unsigned char **)&hostdata->connected->SCp.ptr;
-	count = &hostdata->connected->SCp.this_residual;
-	*data += transferred;
-	*count -= transferred;
-
-	if (hostdata->read_overruns) {
-		int cnt, toPIO;
-
-		if ((NCR5380_read(STATUS_REG) & PHASE_MASK) == p && (p & SR_IO)) {
-			cnt = toPIO = hostdata->read_overruns;
-			if (overrun) {
-				dprintk(NDEBUG_DMA, "Got an input overrun, using saved byte\n");
-				*(*data)++ = saved_data;
-				(*count)--;
-				cnt--;
-				toPIO--;
-			}
-			dprintk(NDEBUG_DMA, "Doing %d-byte PIO to 0x%08lx\n", cnt, (long)*data);
-			NCR5380_transfer_pio(instance, &p, &cnt, data);
-			*count -= toPIO - cnt;
-		}
-	}
-}
-
-
-/**
- * NCR5380_intr - generic NCR5380 irq handler
- * @irq: interrupt number
- * @dev_id: device info
- *
- * Handle interrupts, reestablishing I_T_L or I_T_L_Q nexuses
- * from the disconnected queue, and restarting NCR5380_main()
- * as required.
- *
- * The chip can assert IRQ in any of six different conditions. The IRQ flag
- * is then cleared by reading the Reset Parity/Interrupt Register (RPIR).
- * Three of these six conditions are latched in the Bus and Status Register:
- * - End of DMA (cleared by ending DMA Mode)
- * - Parity error (cleared by reading RPIR)
- * - Loss of BSY (cleared by reading RPIR)
- * Two conditions have flag bits that are not latched:
- * - Bus phase mismatch (non-maskable in DMA Mode, cleared by ending DMA Mode)
- * - Bus reset (non-maskable)
- * The remaining condition has no flag bit at all:
- * - Selection/reselection
- *
- * Hence, establishing the cause(s) of any interrupt is partly guesswork.
- * In "The DP8490 and DP5380 Comparison Guide", National Semiconductor
- * claimed that "the design of the [DP8490] interrupt logic ensures
- * interrupts will not be lost (they can be on the DP5380)."
- * The L5380/53C80 datasheet from LOGIC Devices has more details.
- *
- * Checking for bus reset by reading RST is futile because of interrupt
- * latency, but a bus reset will reset chip logic. Checking for parity error
- * is unnecessary because that interrupt is never enabled. A Loss of BSY
- * condition will clear DMA Mode. We can tell when this occurs because the
- * the Busy Monitor interrupt is enabled together with DMA Mode.
- */
-
-static irqreturn_t NCR5380_intr(int irq, void *dev_id)
-{
-	struct Scsi_Host *instance = dev_id;
-	struct NCR5380_hostdata *hostdata = shost_priv(instance);
-	int handled = 0;
-	unsigned char basr;
-	unsigned long flags;
-
-	spin_lock_irqsave(&hostdata->lock, flags);
-
-	basr = NCR5380_read(BUS_AND_STATUS_REG);
-	if (basr & BASR_IRQ) {
-		unsigned char mr = NCR5380_read(MODE_REG);
-		unsigned char sr = NCR5380_read(STATUS_REG);
-
-		dsprintk(NDEBUG_INTR, instance, "IRQ %d, BASR 0x%02x, SR 0x%02x, MR 0x%02x\n",
-		         irq, basr, sr, mr);
-
-		if ((mr & MR_DMA_MODE) || (mr & MR_MONITOR_BSY)) {
-			/* Probably End of DMA, Phase Mismatch or Loss of BSY.
-			 * We ack IRQ after clearing Mode Register. Workarounds
-			 * for End of DMA errata need to happen in DMA Mode.
-			 */
-
-			dsprintk(NDEBUG_INTR, instance, "interrupt in DMA mode\n");
-
-			if (hostdata->connected) {
-				NCR5380_dma_complete(instance);
-				queue_work(hostdata->work_q, &hostdata->main_task);
-			} else {
-				NCR5380_write(MODE_REG, MR_BASE);
-				NCR5380_read(RESET_PARITY_INTERRUPT_REG);
-			}
-		} else if ((NCR5380_read(CURRENT_SCSI_DATA_REG) & hostdata->id_mask) &&
-		    (sr & (SR_SEL | SR_IO | SR_BSY | SR_RST)) == (SR_SEL | SR_IO)) {
-			/* Probably reselected */
-			NCR5380_write(SELECT_ENABLE_REG, 0);
-			NCR5380_read(RESET_PARITY_INTERRUPT_REG);
-
-			dsprintk(NDEBUG_INTR, instance, "interrupt with SEL and IO\n");
-
-			if (!hostdata->connected) {
-				NCR5380_reselect(instance);
-				queue_work(hostdata->work_q, &hostdata->main_task);
-			}
-			if (!hostdata->connected)
-				NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
-		} else {
-			/* Probably Bus Reset */
-			NCR5380_read(RESET_PARITY_INTERRUPT_REG);
-
-			dsprintk(NDEBUG_INTR, instance, "unknown interrupt\n");
-#ifdef SUN3_SCSI_VME
-			dregs->csr |= CSR_DMA_ENABLE;
-#endif
-		}
-		handled = 1;
-	} else {
-		shost_printk(KERN_NOTICE, instance, "interrupt without IRQ bit\n");
-#ifdef SUN3_SCSI_VME
-		dregs->csr |= CSR_DMA_ENABLE;
-#endif
-	}
-
-	spin_unlock_irqrestore(&hostdata->lock, flags);
-
-	return IRQ_RETVAL(handled);
-}
-
-/*
- * Function : int NCR5380_select(struct Scsi_Host *instance,
- * struct scsi_cmnd *cmd)
- *
- * Purpose : establishes I_T_L or I_T_L_Q nexus for new or existing command,
- * including ARBITRATION, SELECTION, and initial message out for
- * IDENTIFY and queue messages.
- *
- * Inputs : instance - instantiation of the 5380 driver on which this
- * target lives, cmd - SCSI command to execute.
- *
- * Returns cmd if selection failed but should be retried,
- * NULL if selection failed and should not be retried, or
- * NULL if selection succeeded (hostdata->connected == cmd).
- *
- * Side effects :
- * If bus busy, arbitration failed, etc, NCR5380_select() will exit
- * with registers as they should have been on entry - ie
- * SELECT_ENABLE will be set appropriately, the NCR5380
- * will cease to drive any SCSI bus signals.
- *
- * If successful : I_T_L or I_T_L_Q nexus will be established,
- * instance->connected will be set to cmd.
- * SELECT interrupt will be disabled.
- *
- * If failed (no target) : cmd->scsi_done() will be called, and the
- * cmd->result host byte set to DID_BAD_TARGET.
- */
-
-static struct scsi_cmnd *NCR5380_select(struct Scsi_Host *instance,
-                                        struct scsi_cmnd *cmd)
-{
-	struct NCR5380_hostdata *hostdata = shost_priv(instance);
-	unsigned char tmp[3], phase;
-	unsigned char *data;
-	int len;
-	int err;
-
-	NCR5380_dprint(NDEBUG_ARBITRATION, instance);
-	dsprintk(NDEBUG_ARBITRATION, instance, "starting arbitration, id = %d\n",
-	         instance->this_id);
-
-	/*
-	 * Arbitration and selection phases are slow and involve dropping the
-	 * lock, so we have to watch out for EH. An exception handler may
-	 * change 'selecting' to NULL. This function will then return NULL
-	 * so that the caller will forget about 'cmd'. (During information
-	 * transfer phases, EH may change 'connected' to NULL.)
-	 */
-	hostdata->selecting = cmd;
-
-	/*
-	 * Set the phase bits to 0, otherwise the NCR5380 won't drive the
-	 * data bus during SELECTION.
-	 */
-
-	NCR5380_write(TARGET_COMMAND_REG, 0);
-
-	/*
-	 * Start arbitration.
-	 */
-
-	NCR5380_write(OUTPUT_DATA_REG, hostdata->id_mask);
-	NCR5380_write(MODE_REG, MR_ARBITRATE);
-
-	/* The chip now waits for BUS FREE phase. Then after the 800 ns
-	 * Bus Free Delay, arbitration will begin.
-	 */
-
-	spin_unlock_irq(&hostdata->lock);
-	err = NCR5380_poll_politely2(instance, MODE_REG, MR_ARBITRATE, 0,
-	                INITIATOR_COMMAND_REG, ICR_ARBITRATION_PROGRESS,
-	                                       ICR_ARBITRATION_PROGRESS, HZ);
-	spin_lock_irq(&hostdata->lock);
-	if (!(NCR5380_read(MODE_REG) & MR_ARBITRATE)) {
-		/* Reselection interrupt */
-		goto out;
-	}
-	if (!hostdata->selecting) {
-		/* Command was aborted */
-		NCR5380_write(MODE_REG, MR_BASE);
-		goto out;
-	}
-	if (err < 0) {
-		NCR5380_write(MODE_REG, MR_BASE);
-		shost_printk(KERN_ERR, instance,
-		             "select: arbitration timeout\n");
-		goto out;
-	}
-	spin_unlock_irq(&hostdata->lock);
-
-	/* The SCSI-2 arbitration delay is 2.4 us */
-	udelay(3);
-
-	/* Check for lost arbitration */
-	if ((NCR5380_read(INITIATOR_COMMAND_REG) & ICR_ARBITRATION_LOST) ||
-	    (NCR5380_read(CURRENT_SCSI_DATA_REG) & hostdata->id_higher_mask) ||
-	    (NCR5380_read(INITIATOR_COMMAND_REG) & ICR_ARBITRATION_LOST)) {
-		NCR5380_write(MODE_REG, MR_BASE);
-		dsprintk(NDEBUG_ARBITRATION, instance, "lost arbitration, deasserting MR_ARBITRATE\n");
-		spin_lock_irq(&hostdata->lock);
-		goto out;
-	}
-
-	/* After/during arbitration, BSY should be asserted.
-	 * IBM DPES-31080 Version S31Q works now
-	 * Tnx to Thomas_Roesch@m2.maus.de for finding this! (Roman)
-	 */
-	NCR5380_write(INITIATOR_COMMAND_REG,
-		      ICR_BASE | ICR_ASSERT_SEL | ICR_ASSERT_BSY);
-
-	/*
-	 * Again, bus clear + bus settle time is 1.2us, however, this is
-	 * a minimum so we'll udelay ceil(1.2)
-	 */
-
-	if (hostdata->flags & FLAG_TOSHIBA_DELAY)
-		udelay(15);
-	else
-		udelay(2);
-
-	spin_lock_irq(&hostdata->lock);
-
-	/* NCR5380_reselect() clears MODE_REG after a reselection interrupt */
-	if (!(NCR5380_read(MODE_REG) & MR_ARBITRATE))
-		goto out;
-
-	if (!hostdata->selecting) {
-		NCR5380_write(MODE_REG, MR_BASE);
-		NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
-		goto out;
-	}
-
-	dsprintk(NDEBUG_ARBITRATION, instance, "won arbitration\n");
-
-	/*
-	 * Now that we have won arbitration, start Selection process, asserting
-	 * the host and target ID's on the SCSI bus.
-	 */
-
-	NCR5380_write(OUTPUT_DATA_REG, hostdata->id_mask | (1 << scmd_id(cmd)));
-
-	/*
-	 * Raise ATN while SEL is true before BSY goes false from arbitration,
-	 * since this is the only way to guarantee that we'll get a MESSAGE OUT
-	 * phase immediately after selection.
-	 */
-
-	NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_BSY |
-	              ICR_ASSERT_DATA | ICR_ASSERT_ATN | ICR_ASSERT_SEL);
-	NCR5380_write(MODE_REG, MR_BASE);
-
-	/*
-	 * Reselect interrupts must be turned off prior to the dropping of BSY,
-	 * otherwise we will trigger an interrupt.
-	 */
-	NCR5380_write(SELECT_ENABLE_REG, 0);
-
-	spin_unlock_irq(&hostdata->lock);
-
-	/*
-	 * The initiator shall then wait at least two deskew delays and release
-	 * the BSY signal.
-	 */
-	udelay(1);        /* wingel -- wait two bus deskew delay >2*45ns */
-
-	/* Reset BSY */
-	NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_DATA |
-	              ICR_ASSERT_ATN | ICR_ASSERT_SEL);
-
-	/*
-	 * Something weird happens when we cease to drive BSY - looks
-	 * like the board/chip is letting us do another read before the
-	 * appropriate propagation delay has expired, and we're confusing
-	 * a BSY signal from ourselves as the target's response to SELECTION.
-	 *
-	 * A small delay (the 'C++' frontend breaks the pipeline with an
-	 * unnecessary jump, making it work on my 386-33/Trantor T128, the
-	 * tighter 'C' code breaks and requires this) solves the problem -
-	 * the 1 us delay is arbitrary, and only used because this delay will
-	 * be the same on other platforms and since it works here, it should
-	 * work there.
-	 *
-	 * wingel suggests that this could be due to failing to wait
-	 * one deskew delay.
-	 */
-
-	udelay(1);
-
-	dsprintk(NDEBUG_SELECTION, instance, "selecting target %d\n", scmd_id(cmd));
-
-	/*
-	 * The SCSI specification calls for a 250 ms timeout for the actual
-	 * selection.
-	 */
-
-	err = NCR5380_poll_politely(instance, STATUS_REG, SR_BSY, SR_BSY,
-	                            msecs_to_jiffies(250));
-
-	if ((NCR5380_read(STATUS_REG) & (SR_SEL | SR_IO)) == (SR_SEL | SR_IO)) {
-		spin_lock_irq(&hostdata->lock);
-		NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
-		NCR5380_reselect(instance);
-		if (!hostdata->connected)
-			NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
-		shost_printk(KERN_ERR, instance, "reselection after won arbitration?\n");
-		goto out;
-	}
-
-	if (err < 0) {
-		spin_lock_irq(&hostdata->lock);
-		NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
-		NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
-		/* Can't touch cmd if it has been reclaimed by the scsi ML */
-		if (hostdata->selecting) {
-			cmd->result = DID_BAD_TARGET << 16;
-			complete_cmd(instance, cmd);
-			dsprintk(NDEBUG_SELECTION, instance, "target did not respond within 250ms\n");
-			cmd = NULL;
-		}
-		goto out;
-	}
-
-	/*
-	 * No less than two deskew delays after the initiator detects the
-	 * BSY signal is true, it shall release the SEL signal and may
-	 * change the DATA BUS.                                     -wingel
-	 */
-
-	udelay(1);
-
-	NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_ATN);
-
-	/*
-	 * Since we followed the SCSI spec, and raised ATN while SEL
-	 * was true but before BSY was false during selection, the information
-	 * transfer phase should be a MESSAGE OUT phase so that we can send the
-	 * IDENTIFY message.
-	 *
-	 * If SCSI-II tagged queuing is enabled, we also send a SIMPLE_QUEUE_TAG
-	 * message (2 bytes) with a tag ID that we increment with every command
-	 * until it wraps back to 0.
-	 *
-	 * XXX - it turns out that there are some broken SCSI-II devices,
-	 * which claim to support tagged queuing but fail when more than
-	 * some number of commands are issued at once.
-	 */
-
-	/* Wait for start of REQ/ACK handshake */
-
-	err = NCR5380_poll_politely(instance, STATUS_REG, SR_REQ, SR_REQ, HZ);
-	spin_lock_irq(&hostdata->lock);
-	if (err < 0) {
-		shost_printk(KERN_ERR, instance, "select: REQ timeout\n");
-		NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
-		NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
-		goto out;
-	}
-	if (!hostdata->selecting) {
-		do_abort(instance);
-		goto out;
-	}
-
-	dsprintk(NDEBUG_SELECTION, instance, "target %d selected, going into MESSAGE OUT phase.\n",
-	         scmd_id(cmd));
-	tmp[0] = IDENTIFY(1, cmd->device->lun);
-
-#ifdef SUPPORT_TAGS
-	if (cmd->tag != TAG_NONE) {
-		tmp[1] = hostdata->last_message = SIMPLE_QUEUE_TAG;
-		tmp[2] = cmd->tag;
-		len = 3;
-	} else
-		len = 1;
-#else
-	len = 1;
-	cmd->tag = 0;
-#endif /* SUPPORT_TAGS */
-
-	/* Send message(s) */
-	data = tmp;
-	phase = PHASE_MSGOUT;
-	NCR5380_transfer_pio(instance, &phase, &len, &data);
-	dsprintk(NDEBUG_SELECTION, instance, "nexus established.\n");
-	/* XXX need to handle errors here */
-
-	hostdata->connected = cmd;
-#ifndef SUPPORT_TAGS
-	hostdata->busy[cmd->device->id] |= 1 << cmd->device->lun;
-#endif
-#ifdef SUN3_SCSI_VME
-	dregs->csr |= CSR_INTR;
-#endif
-
-	initialize_SCp(cmd);
-
-	cmd = NULL;
-
-out:
-	if (!hostdata->selecting)
-		return NULL;
-	hostdata->selecting = NULL;
-	return cmd;
-}
-
-/*
- * Function : int NCR5380_transfer_pio (struct Scsi_Host *instance,
- * unsigned char *phase, int *count, unsigned char **data)
- *
- * Purpose : transfers data in given phase using polled I/O
- *
- * Inputs : instance - instance of driver, *phase - pointer to
- * what phase is expected, *count - pointer to number of
- * bytes to transfer, **data - pointer to data pointer.
- *
- * Returns : -1 when different phase is entered without transferring
- * maximum number of bytes, 0 if all bytes are transferred or exit
- * is in same phase.
- *
- * Also, *phase, *count, *data are modified in place.
- *
- * XXX Note : handling for bus free may be useful.
- */
-
-/*
- * Note : this code is not as quick as it could be, however it
- * IS 100% reliable, and for the actual data transfer where speed
- * counts, we will always do a pseudo DMA or DMA transfer.
- */
-
-static int NCR5380_transfer_pio(struct Scsi_Host *instance,
-				unsigned char *phase, int *count,
-				unsigned char **data)
-{
-	unsigned char p = *phase, tmp;
-	int c = *count;
-	unsigned char *d = *data;
-
-	/*
-	 * The NCR5380 chip will only drive the SCSI bus when the
-	 * phase specified in the appropriate bits of the TARGET COMMAND
-	 * REGISTER match the STATUS REGISTER
-	 */
-
-	NCR5380_write(TARGET_COMMAND_REG, PHASE_SR_TO_TCR(p));
-
-	do {
-		/*
-		 * Wait for assertion of REQ, after which the phase bits will be
-		 * valid
-		 */
-
-		if (NCR5380_poll_politely(instance, STATUS_REG, SR_REQ, SR_REQ, HZ) < 0)
-			break;
-
-		dsprintk(NDEBUG_HANDSHAKE, instance, "REQ asserted\n");
-
-		/* Check for phase mismatch */
-		if ((NCR5380_read(STATUS_REG) & PHASE_MASK) != p) {
-			dsprintk(NDEBUG_PIO, instance, "phase mismatch\n");
-			NCR5380_dprint_phase(NDEBUG_PIO, instance);
-			break;
-		}
-
-		/* Do actual transfer from SCSI bus to / from memory */
-		if (!(p & SR_IO))
-			NCR5380_write(OUTPUT_DATA_REG, *d);
-		else
-			*d = NCR5380_read(CURRENT_SCSI_DATA_REG);
-
-		++d;
-
-		/*
-		 * The SCSI standard suggests that in MSGOUT phase, the initiator
-		 * should drop ATN on the last byte of the message phase
-		 * after REQ has been asserted for the handshake but before
-		 * the initiator raises ACK.
-		 */
-
-		if (!(p & SR_IO)) {
-			if (!((p & SR_MSG) && c > 1)) {
-				NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_DATA);
-				NCR5380_dprint(NDEBUG_PIO, instance);
-				NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE |
-				              ICR_ASSERT_DATA | ICR_ASSERT_ACK);
-			} else {
-				NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE |
-				              ICR_ASSERT_DATA | ICR_ASSERT_ATN);
-				NCR5380_dprint(NDEBUG_PIO, instance);
-				NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE |
-				              ICR_ASSERT_DATA | ICR_ASSERT_ATN | ICR_ASSERT_ACK);
-			}
-		} else {
-			NCR5380_dprint(NDEBUG_PIO, instance);
-			NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_ACK);
-		}
-
-		if (NCR5380_poll_politely(instance,
-		                          STATUS_REG, SR_REQ, 0, 5 * HZ) < 0)
-			break;
-
-		dsprintk(NDEBUG_HANDSHAKE, instance, "REQ negated, handshake complete\n");
-
-/*
- * We have several special cases to consider during REQ/ACK handshaking :
- * 1.  We were in MSGOUT phase, and we are on the last byte of the
- * message.  ATN must be dropped as ACK is dropped.
- *
- * 2.  We are in a MSGIN phase, and we are on the last byte of the
- * message.  We must exit with ACK asserted, so that the calling
- * code may raise ATN before dropping ACK to reject the message.
- *
- * 3.  ACK and ATN are clear and the target may proceed as normal.
- */
-		if (!(p == PHASE_MSGIN && c == 1)) {
-			if (p == PHASE_MSGOUT && c > 1)
-				NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_ATN);
-			else
-				NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
-		}
-	} while (--c);
-
-	dsprintk(NDEBUG_PIO, instance, "residual %d\n", c);
-
-	*count = c;
-	*data = d;
-	tmp = NCR5380_read(STATUS_REG);
-	/* The phase read from the bus is valid if either REQ is (already)
-	 * asserted or if ACK hasn't been released yet. The latter applies if
-	 * we're in MSG IN, DATA IN or STATUS and all bytes have been received.
-	 */
-	if ((tmp & SR_REQ) || ((tmp & SR_IO) && c == 0))
-		*phase = tmp & PHASE_MASK;
-	else
-		*phase = PHASE_UNKNOWN;
-
-	if (!c || (*phase == p))
-		return 0;
-	else
-		return -1;
-}
-
-/**
- * do_reset - issue a reset command
- * @instance: adapter to reset
- *
- * Issue a reset sequence to the NCR5380 and try and get the bus
- * back into sane shape.
- *
- * This clears the reset interrupt flag because there may be no handler for
- * it. When the driver is initialized, the NCR5380_intr() handler has not yet
- * been installed. And when in EH we may have released the ST DMA interrupt.
- */
-
-static void do_reset(struct Scsi_Host *instance)
-{
-	unsigned long flags;
-
-	local_irq_save(flags);
-	NCR5380_write(TARGET_COMMAND_REG,
-	              PHASE_SR_TO_TCR(NCR5380_read(STATUS_REG) & PHASE_MASK));
-	NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_RST);
-	udelay(50);
-	NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
-	(void)NCR5380_read(RESET_PARITY_INTERRUPT_REG);
-	local_irq_restore(flags);
-}
-
-/**
- * do_abort - abort the currently established nexus by going to
- * MESSAGE OUT phase and sending an ABORT message.
- * @instance: relevant scsi host instance
- *
- * Returns 0 on success, -1 on failure.
- */
-
-static int do_abort(struct Scsi_Host *instance)
-{
-	unsigned char *msgptr, phase, tmp;
-	int len;
-	int rc;
-
-	/* Request message out phase */
-	NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_ATN);
-
-	/*
-	 * Wait for the target to indicate a valid phase by asserting
-	 * REQ.  Once this happens, we'll have either a MSGOUT phase
-	 * and can immediately send the ABORT message, or we'll have some
-	 * other phase and will have to source/sink data.
-	 *
-	 * We really don't care what value was on the bus or what value
-	 * the target sees, so we just handshake.
-	 */
-
-	rc = NCR5380_poll_politely(instance, STATUS_REG, SR_REQ, SR_REQ, 10 * HZ);
-	if (rc < 0)
-		goto timeout;
-
-	tmp = NCR5380_read(STATUS_REG) & PHASE_MASK;
-
-	NCR5380_write(TARGET_COMMAND_REG, PHASE_SR_TO_TCR(tmp));
-
-	if (tmp != PHASE_MSGOUT) {
-		NCR5380_write(INITIATOR_COMMAND_REG,
-		              ICR_BASE | ICR_ASSERT_ATN | ICR_ASSERT_ACK);
-		rc = NCR5380_poll_politely(instance, STATUS_REG, SR_REQ, 0, 3 * HZ);
-		if (rc < 0)
-			goto timeout;
-		NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_ATN);
-	}
-
-	tmp = ABORT;
-	msgptr = &tmp;
-	len = 1;
-	phase = PHASE_MSGOUT;
-	NCR5380_transfer_pio(instance, &phase, &len, &msgptr);
-
-	/*
-	 * If we got here, and the command completed successfully,
-	 * we're about to go into bus free state.
-	 */
-
-	return len ? -1 : 0;
-
-timeout:
-	NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
-	return -1;
-}
-
-
-/*
- * Function : int NCR5380_transfer_dma (struct Scsi_Host *instance,
- * unsigned char *phase, int *count, unsigned char **data)
- *
- * Purpose : transfers data in given phase using either real
- * or pseudo DMA.
- *
- * Inputs : instance - instance of driver, *phase - pointer to
- * what phase is expected, *count - pointer to number of
- * bytes to transfer, **data - pointer to data pointer.
- *
- * Returns : -1 when different phase is entered without transferring
- * maximum number of bytes, 0 if all bytes or transferred or exit
- * is in same phase.
- *
- * Also, *phase, *count, *data are modified in place.
- */
-
-
-static int NCR5380_transfer_dma(struct Scsi_Host *instance,
-				unsigned char *phase, int *count,
-				unsigned char **data)
-{
-	struct NCR5380_hostdata *hostdata = shost_priv(instance);
-	register int c = *count;
-	register unsigned char p = *phase;
-
-#if defined(CONFIG_SUN3)
-	/* sanity check */
-	if (!sun3_dma_setup_done) {
-		pr_err("scsi%d: transfer_dma without setup!\n",
-		       instance->host_no);
-		BUG();
-	}
-	hostdata->dma_len = c;
-
-	dsprintk(NDEBUG_DMA, instance, "initializing DMA %s: length %d, address %p\n",
-	         (p & SR_IO) ? "receive" : "send", c, *data);
-
-	/* netbsd turns off ints here, why not be safe and do it too */
-
-	/* send start chain */
-	sun3scsi_dma_start(c, *data);
-
-	NCR5380_write(TARGET_COMMAND_REG, PHASE_SR_TO_TCR(p));
-	NCR5380_write(MODE_REG, MR_BASE | MR_DMA_MODE | MR_MONITOR_BSY |
-	                        MR_ENABLE_EOP_INTR);
-	if (p & SR_IO) {
-		NCR5380_write(INITIATOR_COMMAND_REG, 0);
-		NCR5380_write(START_DMA_INITIATOR_RECEIVE_REG, 0);
-	} else {
-		NCR5380_write(INITIATOR_COMMAND_REG, ICR_ASSERT_DATA);
-		NCR5380_write(START_DMA_SEND_REG, 0);
-	}
-
-#ifdef SUN3_SCSI_VME
-	dregs->csr |= CSR_DMA_ENABLE;
-#endif
-
-	sun3_dma_active = 1;
-
-#else /* !defined(CONFIG_SUN3) */
-	register unsigned char *d = *data;
-	unsigned char tmp;
-
-	if ((tmp = (NCR5380_read(STATUS_REG) & PHASE_MASK)) != p) {
-		*phase = tmp;
-		return -1;
-	}
-
-	if (hostdata->read_overruns && (p & SR_IO))
-		c -= hostdata->read_overruns;
-
-	dsprintk(NDEBUG_DMA, instance, "initializing DMA %s: length %d, address %p\n",
-	         (p & SR_IO) ? "receive" : "send", c, d);
-
-	NCR5380_write(TARGET_COMMAND_REG, PHASE_SR_TO_TCR(p));
-	NCR5380_write(MODE_REG, MR_BASE | MR_DMA_MODE | MR_MONITOR_BSY |
-	                        MR_ENABLE_EOP_INTR);
-
-	if (!(hostdata->flags & FLAG_LATE_DMA_SETUP)) {
-		/* On the Medusa, it is a must to initialize the DMA before
-		 * starting the NCR. This is also the cleaner way for the TT.
-		 */
-		hostdata->dma_len = (p & SR_IO) ?
-			NCR5380_dma_read_setup(instance, d, c) :
-			NCR5380_dma_write_setup(instance, d, c);
-	}
-
-	if (p & SR_IO)
-		NCR5380_write(START_DMA_INITIATOR_RECEIVE_REG, 0);
-	else {
-		NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_DATA);
-		NCR5380_write(START_DMA_SEND_REG, 0);
-	}
-
-	if (hostdata->flags & FLAG_LATE_DMA_SETUP) {
-		/* On the Falcon, the DMA setup must be done after the last */
-		/* NCR access, else the DMA setup gets trashed!
-		 */
-		hostdata->dma_len = (p & SR_IO) ?
-			NCR5380_dma_read_setup(instance, d, c) :
-			NCR5380_dma_write_setup(instance, d, c);
-	}
-#endif /* !defined(CONFIG_SUN3) */
-
-	return 0;
-}
-
-/*
- * Function : NCR5380_information_transfer (struct Scsi_Host *instance)
- *
- * Purpose : run through the various SCSI phases and do as the target
- * directs us to.  Operates on the currently connected command,
- * instance->connected.
- *
- * Inputs : instance, instance for which we are doing commands
- *
- * Side effects : SCSI things happen, the disconnected queue will be
- * modified if a command disconnects, *instance->connected will
- * change.
- *
- * XXX Note : we need to watch for bus free or a reset condition here
- * to recover from an unexpected bus free condition.
- */
-
-static void NCR5380_information_transfer(struct Scsi_Host *instance)
-{
-	struct NCR5380_hostdata *hostdata = shost_priv(instance);
-	unsigned char msgout = NOP;
-	int sink = 0;
-	int len;
-	int transfersize;
-	unsigned char *data;
-	unsigned char phase, tmp, extended_msg[10], old_phase = 0xff;
-	struct scsi_cmnd *cmd;
-
-#ifdef SUN3_SCSI_VME
-	dregs->csr |= CSR_INTR;
-#endif
-
-	while ((cmd = hostdata->connected)) {
-		struct NCR5380_cmd *ncmd = scsi_cmd_priv(cmd);
-
-		tmp = NCR5380_read(STATUS_REG);
-		/* We only have a valid SCSI phase when REQ is asserted */
-		if (tmp & SR_REQ) {
-			phase = (tmp & PHASE_MASK);
-			if (phase != old_phase) {
-				old_phase = phase;
-				NCR5380_dprint_phase(NDEBUG_INFORMATION, instance);
-			}
-#if defined(CONFIG_SUN3)
-			if (phase == PHASE_CMDOUT) {
-				void *d;
-				unsigned long count;
-
-				if (!cmd->SCp.this_residual && cmd->SCp.buffers_residual) {
-					count = cmd->SCp.buffer->length;
-					d = sg_virt(cmd->SCp.buffer);
-				} else {
-					count = cmd->SCp.this_residual;
-					d = cmd->SCp.ptr;
-				}
-				/* this command setup for dma yet? */
-				if (sun3_dma_setup_done != cmd &&
-				    sun3scsi_dma_xfer_len(count, cmd) > 0) {
-					sun3scsi_dma_setup(instance, d, count,
-					                   rq_data_dir(cmd->request));
-					sun3_dma_setup_done = cmd;
-				}
-#ifdef SUN3_SCSI_VME
-				dregs->csr |= CSR_INTR;
-#endif
-			}
-#endif /* CONFIG_SUN3 */
-
-			if (sink && (phase != PHASE_MSGOUT)) {
-				NCR5380_write(TARGET_COMMAND_REG, PHASE_SR_TO_TCR(tmp));
-
-				NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_ATN |
-				              ICR_ASSERT_ACK);
-				while (NCR5380_read(STATUS_REG) & SR_REQ)
-					;
-				NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE |
-				              ICR_ASSERT_ATN);
-				sink = 0;
-				continue;
-			}
-
-			switch (phase) {
-			case PHASE_DATAOUT:
-#if (NDEBUG & NDEBUG_NO_DATAOUT)
-				shost_printk(KERN_DEBUG, instance, "NDEBUG_NO_DATAOUT set, attempted DATAOUT aborted\n");
-				sink = 1;
-				do_abort(instance);
-				cmd->result = DID_ERROR << 16;
-				complete_cmd(instance, cmd);
-				hostdata->connected = NULL;
-				return;
-#endif
-			case PHASE_DATAIN:
-				/*
-				 * If there is no room left in the current buffer in the
-				 * scatter-gather list, move onto the next one.
-				 */
-
-				if (!cmd->SCp.this_residual && cmd->SCp.buffers_residual) {
-					++cmd->SCp.buffer;
-					--cmd->SCp.buffers_residual;
-					cmd->SCp.this_residual = cmd->SCp.buffer->length;
-					cmd->SCp.ptr = sg_virt(cmd->SCp.buffer);
-					merge_contiguous_buffers(cmd);
-					dsprintk(NDEBUG_INFORMATION, instance, "%d bytes and %d buffers left\n",
-					         cmd->SCp.this_residual,
-					         cmd->SCp.buffers_residual);
-				}
-
-				/*
-				 * The preferred transfer method is going to be
-				 * PSEUDO-DMA for systems that are strictly PIO,
-				 * since we can let the hardware do the handshaking.
-				 *
-				 * For this to work, we need to know the transfersize
-				 * ahead of time, since the pseudo-DMA code will sit
-				 * in an unconditional loop.
-				 */
-
-#if !defined(CONFIG_SUN3)
-				transfersize = 0;
-				if (!cmd->device->borken)
-#endif
-					transfersize = NCR5380_dma_xfer_len(instance, cmd, phase);
-
-				if (transfersize > 0) {
-					len = transfersize;
-					cmd->SCp.phase = phase;
-					if (NCR5380_transfer_dma(instance, &phase,
-					    &len, (unsigned char **)&cmd->SCp.ptr)) {
-						/*
-						 * If the watchdog timer fires, all future
-						 * accesses to this device will use the
-						 * polled-IO.
-						 */
-						scmd_printk(KERN_INFO, cmd,
-							"switching to slow handshake\n");
-						cmd->device->borken = 1;
-						sink = 1;
-						do_abort(instance);
-						cmd->result = DID_ERROR << 16;
-						/* XXX - need to source or sink data here, as appropriate */
-					} else
-						return;
-				} else {
-					/* Break up transfer into 3 ms chunks,
-					 * presuming 6 accesses per handshake.
-					 */
-					transfersize = min((unsigned long)cmd->SCp.this_residual,
-					                   hostdata->accesses_per_ms / 2);
-					len = transfersize;
-					NCR5380_transfer_pio(instance, &phase, &len,
-					                     (unsigned char **)&cmd->SCp.ptr);
-					cmd->SCp.this_residual -= transfersize - len;
-				}
-#if defined(CONFIG_SUN3)
-				/* if we had intended to dma that command clear it */
-				if (sun3_dma_setup_done == cmd)
-					sun3_dma_setup_done = NULL;
-#endif
-				return;
-			case PHASE_MSGIN:
-				len = 1;
-				data = &tmp;
-				NCR5380_transfer_pio(instance, &phase, &len, &data);
-				cmd->SCp.Message = tmp;
-
-				switch (tmp) {
-				case ABORT:
-				case COMMAND_COMPLETE:
-					/* Accept message by clearing ACK */
-					NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
-					dsprintk(NDEBUG_QUEUES, instance,
-					         "COMMAND COMPLETE %p target %d lun %llu\n",
-					         cmd, scmd_id(cmd), cmd->device->lun);
-
-					hostdata->connected = NULL;
-#ifdef SUPPORT_TAGS
-					cmd_free_tag(cmd);
-					if (status_byte(cmd->SCp.Status) == QUEUE_FULL) {
-						u8 lun = cmd->device->lun;
-						struct tag_alloc *ta = &hostdata->TagAlloc[scmd_id(cmd)][lun];
-
-						dsprintk(NDEBUG_TAGS, instance,
-						         "QUEUE_FULL %p target %d lun %d nr_allocated %d\n",
-						         cmd, scmd_id(cmd), lun, ta->nr_allocated);
-						if (ta->queue_size > ta->nr_allocated)
-							ta->queue_size = ta->nr_allocated;
-					}
-#endif
-
-					cmd->result &= ~0xffff;
-					cmd->result |= cmd->SCp.Status;
-					cmd->result |= cmd->SCp.Message << 8;
-
-					if (cmd->cmnd[0] == REQUEST_SENSE)
-						complete_cmd(instance, cmd);
-					else {
-						if (cmd->SCp.Status == SAM_STAT_CHECK_CONDITION ||
-						    cmd->SCp.Status == SAM_STAT_COMMAND_TERMINATED) {
-							dsprintk(NDEBUG_QUEUES, instance, "autosense: adding cmd %p to tail of autosense queue\n",
-							         cmd);
-							list_add_tail(&ncmd->list,
-							              &hostdata->autosense);
-						} else
-							complete_cmd(instance, cmd);
-					}
-
-					/*
-					 * Restore phase bits to 0 so an interrupted selection,
-					 * arbitration can resume.
-					 */
-					NCR5380_write(TARGET_COMMAND_REG, 0);
-
-					/* Enable reselect interrupts */
-					NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
-
-					maybe_release_dma_irq(instance);
-					return;
-				case MESSAGE_REJECT:
-					/* Accept message by clearing ACK */
-					NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
-					switch (hostdata->last_message) {
-					case HEAD_OF_QUEUE_TAG:
-					case ORDERED_QUEUE_TAG:
-					case SIMPLE_QUEUE_TAG:
-						/* The target obviously doesn't support tagged
-						 * queuing, even though it announced this ability in
-						 * its INQUIRY data ?!? (maybe only this LUN?) Ok,
-						 * clear 'tagged_supported' and lock the LUN, since
-						 * the command is treated as untagged further on.
-						 */
-						cmd->device->tagged_supported = 0;
-						hostdata->busy[cmd->device->id] |= (1 << cmd->device->lun);
-						cmd->tag = TAG_NONE;
-						dsprintk(NDEBUG_TAGS, instance, "target %d lun %llu rejected QUEUE_TAG message; tagged queuing disabled\n",
-						         scmd_id(cmd), cmd->device->lun);
-						break;
-					}
-					break;
-				case DISCONNECT:
-					/* Accept message by clearing ACK */
-					NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
-					hostdata->connected = NULL;
-					list_add(&ncmd->list, &hostdata->disconnected);
-					dsprintk(NDEBUG_INFORMATION | NDEBUG_QUEUES,
-					         instance, "connected command %p for target %d lun %llu moved to disconnected queue\n",
-					         cmd, scmd_id(cmd), cmd->device->lun);
-
-					/*
-					 * Restore phase bits to 0 so an interrupted selection,
-					 * arbitration can resume.
-					 */
-					NCR5380_write(TARGET_COMMAND_REG, 0);
-
-					/* Enable reselect interrupts */
-					NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
-#ifdef SUN3_SCSI_VME
-					dregs->csr |= CSR_DMA_ENABLE;
-#endif
-					return;
-					/*
-					 * The SCSI data pointer is *IMPLICITLY* saved on a disconnect
-					 * operation, in violation of the SCSI spec so we can safely
-					 * ignore SAVE/RESTORE pointers calls.
-					 *
-					 * Unfortunately, some disks violate the SCSI spec and
-					 * don't issue the required SAVE_POINTERS message before
-					 * disconnecting, and we have to break spec to remain
-					 * compatible.
-					 */
-				case SAVE_POINTERS:
-				case RESTORE_POINTERS:
-					/* Accept message by clearing ACK */
-					NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
-					break;
-				case EXTENDED_MESSAGE:
-					/*
-					 * Start the message buffer with the EXTENDED_MESSAGE
-					 * byte, since spi_print_msg() wants the whole thing.
-					 */
-					extended_msg[0] = EXTENDED_MESSAGE;
-					/* Accept first byte by clearing ACK */
-					NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
-
-					spin_unlock_irq(&hostdata->lock);
-
-					dsprintk(NDEBUG_EXTENDED, instance, "receiving extended message\n");
-
-					len = 2;
-					data = extended_msg + 1;
-					phase = PHASE_MSGIN;
-					NCR5380_transfer_pio(instance, &phase, &len, &data);
-					dsprintk(NDEBUG_EXTENDED, instance, "length %d, code 0x%02x\n",
-					         (int)extended_msg[1],
-					         (int)extended_msg[2]);
-
-					if (!len && extended_msg[1] > 0 &&
-					    extended_msg[1] <= sizeof(extended_msg) - 2) {
-						/* Accept third byte by clearing ACK */
-						NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
-						len = extended_msg[1] - 1;
-						data = extended_msg + 3;
-						phase = PHASE_MSGIN;
-
-						NCR5380_transfer_pio(instance, &phase, &len, &data);
-						dsprintk(NDEBUG_EXTENDED, instance, "message received, residual %d\n",
-						         len);
-
-						switch (extended_msg[2]) {
-						case EXTENDED_SDTR:
-						case EXTENDED_WDTR:
-						case EXTENDED_MODIFY_DATA_POINTER:
-						case EXTENDED_EXTENDED_IDENTIFY:
-							tmp = 0;
-						}
-					} else if (len) {
-						shost_printk(KERN_ERR, instance, "error receiving extended message\n");
-						tmp = 0;
-					} else {
-						shost_printk(KERN_NOTICE, instance, "extended message code %02x length %d is too long\n",
-						             extended_msg[2], extended_msg[1]);
-						tmp = 0;
-					}
-
-					spin_lock_irq(&hostdata->lock);
-					if (!hostdata->connected)
-						return;
-
-					/* Fall through to reject message */
-
-					/*
-					 * If we get something weird that we aren't expecting,
-					 * reject it.
-					 */
-				default:
-					if (!tmp) {
-						shost_printk(KERN_ERR, instance, "rejecting message ");
-						spi_print_msg(extended_msg);
-						printk("\n");
-					} else if (tmp != EXTENDED_MESSAGE)
-						scmd_printk(KERN_INFO, cmd,
-						            "rejecting unknown message %02x\n",
-						            tmp);
-					else
-						scmd_printk(KERN_INFO, cmd,
-						            "rejecting unknown extended message code %02x, length %d\n",
-						            extended_msg[1], extended_msg[0]);
-
-					msgout = MESSAGE_REJECT;
-					NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_ATN);
-					break;
-				} /* switch (tmp) */
-				break;
-			case PHASE_MSGOUT:
-				len = 1;
-				data = &msgout;
-				hostdata->last_message = msgout;
-				NCR5380_transfer_pio(instance, &phase, &len, &data);
-				if (msgout == ABORT) {
-					hostdata->connected = NULL;
-					cmd->result = DID_ERROR << 16;
-					complete_cmd(instance, cmd);
-					maybe_release_dma_irq(instance);
-					NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
-					return;
-				}
-				msgout = NOP;
-				break;
-			case PHASE_CMDOUT:
-				len = cmd->cmd_len;
-				data = cmd->cmnd;
-				/*
-				 * XXX for performance reasons, on machines with a
-				 * PSEUDO-DMA architecture we should probably
-				 * use the dma transfer function.
-				 */
-				NCR5380_transfer_pio(instance, &phase, &len, &data);
-				break;
-			case PHASE_STATIN:
-				len = 1;
-				data = &tmp;
-				NCR5380_transfer_pio(instance, &phase, &len, &data);
-				cmd->SCp.Status = tmp;
-				break;
-			default:
-				shost_printk(KERN_ERR, instance, "unknown phase\n");
-				NCR5380_dprint(NDEBUG_ANY, instance);
-			} /* switch(phase) */
-		} else {
-			spin_unlock_irq(&hostdata->lock);
-			NCR5380_poll_politely(instance, STATUS_REG, SR_REQ, SR_REQ, HZ);
-			spin_lock_irq(&hostdata->lock);
-		}
-	}
-}
-
-/*
- * Function : void NCR5380_reselect (struct Scsi_Host *instance)
- *
- * Purpose : does reselection, initializing the instance->connected
- * field to point to the scsi_cmnd for which the I_T_L or I_T_L_Q
- * nexus has been reestablished,
- *
- * Inputs : instance - this instance of the NCR5380.
- */
-
-
-/* it might eventually prove necessary to do a dma setup on
-   reselection, but it doesn't seem to be needed now -- sam */
-
-static void NCR5380_reselect(struct Scsi_Host *instance)
-{
-	struct NCR5380_hostdata *hostdata = shost_priv(instance);
-	unsigned char target_mask;
-	unsigned char lun;
-#ifdef SUPPORT_TAGS
-	unsigned char tag;
-#endif
-	unsigned char msg[3];
-	int __maybe_unused len;
-	unsigned char __maybe_unused *data, __maybe_unused phase;
-	struct NCR5380_cmd *ncmd;
-	struct scsi_cmnd *tmp;
-
-	/*
-	 * Disable arbitration, etc. since the host adapter obviously
-	 * lost, and tell an interrupted NCR5380_select() to restart.
-	 */
-
-	NCR5380_write(MODE_REG, MR_BASE);
-
-	target_mask = NCR5380_read(CURRENT_SCSI_DATA_REG) & ~(hostdata->id_mask);
-
-	dsprintk(NDEBUG_RESELECTION, instance, "reselect\n");
-
-	/*
-	 * At this point, we have detected that our SCSI ID is on the bus,
-	 * SEL is true and BSY was false for at least one bus settle delay
-	 * (400 ns).
-	 *
-	 * We must assert BSY ourselves, until the target drops the SEL
-	 * signal.
-	 */
-
-	NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_BSY);
-	if (NCR5380_poll_politely(instance,
-	                          STATUS_REG, SR_SEL, 0, 2 * HZ) < 0) {
-		NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
-		return;
-	}
-	NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
-
-	/*
-	 * Wait for target to go into MSGIN.
-	 */
-
-	if (NCR5380_poll_politely(instance,
-	                          STATUS_REG, SR_REQ, SR_REQ, 2 * HZ) < 0) {
-		do_abort(instance);
-		return;
-	}
-
-#if defined(CONFIG_SUN3)
-	/* acknowledge toggle to MSGIN */
-	NCR5380_write(TARGET_COMMAND_REG, PHASE_SR_TO_TCR(PHASE_MSGIN));
-
-	/* peek at the byte without really hitting the bus */
-	msg[0] = NCR5380_read(CURRENT_SCSI_DATA_REG);
-#else
-	len = 1;
-	data = msg;
-	phase = PHASE_MSGIN;
-	NCR5380_transfer_pio(instance, &phase, &len, &data);
-
-	if (len) {
-		do_abort(instance);
-		return;
-	}
-#endif
-
-	if (!(msg[0] & 0x80)) {
-		shost_printk(KERN_ERR, instance, "expecting IDENTIFY message, got ");
-		spi_print_msg(msg);
-		printk("\n");
-		do_abort(instance);
-		return;
-	}
-	lun = msg[0] & 0x07;
-
-#if defined(SUPPORT_TAGS) && !defined(CONFIG_SUN3)
-	/* If the phase is still MSGIN, the target wants to send some more
-	 * messages. In case it supports tagged queuing, this is probably a
-	 * SIMPLE_QUEUE_TAG for the I_T_L_Q nexus.
-	 */
-	tag = TAG_NONE;
-	if (phase == PHASE_MSGIN && (hostdata->flags & FLAG_TAGGED_QUEUING)) {
-		/* Accept previous IDENTIFY message by clearing ACK */
-		NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
-		len = 2;
-		data = msg + 1;
-		if (!NCR5380_transfer_pio(instance, &phase, &len, &data) &&
-		    msg[1] == SIMPLE_QUEUE_TAG)
-			tag = msg[2];
-		dsprintk(NDEBUG_TAGS, instance, "reselect: target mask %02x, lun %d sent tag %d\n",
-		         target_mask, lun, tag);
-	}
-#endif
-
-	/*
-	 * Find the command corresponding to the I_T_L or I_T_L_Q  nexus we
-	 * just reestablished, and remove it from the disconnected queue.
-	 */
-
-	tmp = NULL;
-	list_for_each_entry(ncmd, &hostdata->disconnected, list) {
-		struct scsi_cmnd *cmd = NCR5380_to_scmd(ncmd);
-
-		if (target_mask == (1 << scmd_id(cmd)) &&
-		    lun == (u8)cmd->device->lun
-#ifdef SUPPORT_TAGS
-		    && (tag == cmd->tag)
-#endif
-		    ) {
-			list_del(&ncmd->list);
-			tmp = cmd;
-			break;
-		}
-	}
-
-	if (tmp) {
-		dsprintk(NDEBUG_RESELECTION | NDEBUG_QUEUES, instance,
-		         "reselect: removed %p from disconnected queue\n", tmp);
-	} else {
-
-#ifdef SUPPORT_TAGS
-		shost_printk(KERN_ERR, instance, "target bitmask 0x%02x lun %d tag %d not in disconnected queue.\n",
-		             target_mask, lun, tag);
-#else
-		shost_printk(KERN_ERR, instance, "target bitmask 0x%02x lun %d not in disconnected queue.\n",
-		             target_mask, lun);
-#endif
-		/*
-		 * Since we have an established nexus that we can't do anything
-		 * with, we must abort it.
-		 */
-		do_abort(instance);
-		return;
-	}
-
-#if defined(CONFIG_SUN3)
-	/* engage dma setup for the command we just saw */
-	{
-		void *d;
-		unsigned long count;
-
-		if (!tmp->SCp.this_residual && tmp->SCp.buffers_residual) {
-			count = tmp->SCp.buffer->length;
-			d = sg_virt(tmp->SCp.buffer);
-		} else {
-			count = tmp->SCp.this_residual;
-			d = tmp->SCp.ptr;
-		}
-		/* setup this command for dma if not already */
-		if (sun3_dma_setup_done != tmp &&
-		    sun3scsi_dma_xfer_len(count, tmp) > 0) {
-			sun3scsi_dma_setup(instance, d, count,
-			                   rq_data_dir(tmp->request));
-			sun3_dma_setup_done = tmp;
-		}
-	}
-
-	NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_ACK);
-#endif
-
-	/* Accept message by clearing ACK */
-	NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
-
-#if defined(SUPPORT_TAGS) && defined(CONFIG_SUN3)
-	/* If the phase is still MSGIN, the target wants to send some more
-	 * messages. In case it supports tagged queuing, this is probably a
-	 * SIMPLE_QUEUE_TAG for the I_T_L_Q nexus.
-	 */
-	tag = TAG_NONE;
-	if (phase == PHASE_MSGIN && setup_use_tagged_queuing) {
-		/* Accept previous IDENTIFY message by clearing ACK */
-		NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
-		len = 2;
-		data = msg + 1;
-		if (!NCR5380_transfer_pio(instance, &phase, &len, &data) &&
-		    msg[1] == SIMPLE_QUEUE_TAG)
-			tag = msg[2];
-		dsprintk(NDEBUG_TAGS, instance, "reselect: target mask %02x, lun %d sent tag %d\n"
-		         target_mask, lun, tag);
-	}
-#endif
-
-	hostdata->connected = tmp;
-	dsprintk(NDEBUG_RESELECTION, instance, "nexus established, target %d, lun %llu, tag %d\n",
-	         scmd_id(tmp), tmp->device->lun, tmp->tag);
-}
-
-
-/**
- * list_find_cmd - test for presence of a command in a linked list
- * @haystack: list of commands
- * @needle: command to search for
- */
-
-static bool list_find_cmd(struct list_head *haystack,
-                          struct scsi_cmnd *needle)
-{
-	struct NCR5380_cmd *ncmd;
-
-	list_for_each_entry(ncmd, haystack, list)
-		if (NCR5380_to_scmd(ncmd) == needle)
-			return true;
-	return false;
-}
-
-/**
- * list_remove_cmd - remove a command from linked list
- * @haystack: list of commands
- * @needle: command to remove
- */
-
-static bool list_del_cmd(struct list_head *haystack,
-                         struct scsi_cmnd *needle)
-{
-	if (list_find_cmd(haystack, needle)) {
-		struct NCR5380_cmd *ncmd = scsi_cmd_priv(needle);
-
-		list_del(&ncmd->list);
-		return true;
-	}
-	return false;
-}
-
-/**
- * NCR5380_abort - scsi host eh_abort_handler() method
- * @cmd: the command to be aborted
- *
- * Try to abort a given command by removing it from queues and/or sending
- * the target an abort message. This may not succeed in causing a target
- * to abort the command. Nonetheless, the low-level driver must forget about
- * the command because the mid-layer reclaims it and it may be re-issued.
- *
- * The normal path taken by a command is as follows. For EH we trace this
- * same path to locate and abort the command.
- *
- * unissued -> selecting -> [unissued -> selecting ->]... connected ->
- * [disconnected -> connected ->]...
- * [autosense -> connected ->] done
- *
- * If cmd was not found at all then presumably it has already been completed,
- * in which case return SUCCESS to try to avoid further EH measures.
- *
- * If the command has not completed yet, we must not fail to find it.
- * We have no option but to forget the aborted command (even if it still
- * lacks sense data). The mid-layer may re-issue a command that is in error
- * recovery (see scsi_send_eh_cmnd), but the logic and data structures in
- * this driver are such that a command can appear on one queue only.
- *
- * The lock protects driver data structures, but EH handlers also use it
- * to serialize their own execution and prevent their own re-entry.
- */
-
-static int NCR5380_abort(struct scsi_cmnd *cmd)
-{
-	struct Scsi_Host *instance = cmd->device->host;
-	struct NCR5380_hostdata *hostdata = shost_priv(instance);
-	unsigned long flags;
-	int result = SUCCESS;
-
-	spin_lock_irqsave(&hostdata->lock, flags);
-
-#if (NDEBUG & NDEBUG_ANY)
-	scmd_printk(KERN_INFO, cmd, __func__);
-#endif
-	NCR5380_dprint(NDEBUG_ANY, instance);
-	NCR5380_dprint_phase(NDEBUG_ANY, instance);
-
-	if (list_del_cmd(&hostdata->unissued, cmd)) {
-		dsprintk(NDEBUG_ABORT, instance,
-		         "abort: removed %p from issue queue\n", cmd);
-		cmd->result = DID_ABORT << 16;
-		cmd->scsi_done(cmd); /* No tag or busy flag to worry about */
-		goto out;
-	}
-
-	if (hostdata->selecting == cmd) {
-		dsprintk(NDEBUG_ABORT, instance,
-		         "abort: cmd %p == selecting\n", cmd);
-		hostdata->selecting = NULL;
-		cmd->result = DID_ABORT << 16;
-		complete_cmd(instance, cmd);
-		goto out;
-	}
-
-	if (list_del_cmd(&hostdata->disconnected, cmd)) {
-		dsprintk(NDEBUG_ABORT, instance,
-		         "abort: removed %p from disconnected list\n", cmd);
-		/* Can't call NCR5380_select() and send ABORT because that
-		 * means releasing the lock. Need a bus reset.
-		 */
-		set_host_byte(cmd, DID_ERROR);
-		complete_cmd(instance, cmd);
-		result = FAILED;
-		goto out;
-	}
-
-	if (hostdata->connected == cmd) {
-		dsprintk(NDEBUG_ABORT, instance, "abort: cmd %p is connected\n", cmd);
-		hostdata->connected = NULL;
-		hostdata->dma_len = 0;
-		if (do_abort(instance)) {
-			set_host_byte(cmd, DID_ERROR);
-			complete_cmd(instance, cmd);
-			result = FAILED;
-			goto out;
-		}
-		set_host_byte(cmd, DID_ABORT);
-		complete_cmd(instance, cmd);
-		goto out;
-	}
-
-	if (list_del_cmd(&hostdata->autosense, cmd)) {
-		dsprintk(NDEBUG_ABORT, instance,
-		         "abort: removed %p from sense queue\n", cmd);
-		set_host_byte(cmd, DID_ERROR);
-		complete_cmd(instance, cmd);
-	}
-
-out:
-	if (result == FAILED)
-		dsprintk(NDEBUG_ABORT, instance, "abort: failed to abort %p\n", cmd);
-	else
-		dsprintk(NDEBUG_ABORT, instance, "abort: successfully aborted %p\n", cmd);
-
-	queue_work(hostdata->work_q, &hostdata->main_task);
-	maybe_release_dma_irq(instance);
-	spin_unlock_irqrestore(&hostdata->lock, flags);
-
-	return result;
-}
-
-
-/**
- * NCR5380_bus_reset - reset the SCSI bus
- * @cmd: SCSI command undergoing EH
- *
- * Returns SUCCESS
- */
-
-static int NCR5380_bus_reset(struct scsi_cmnd *cmd)
-{
-	struct Scsi_Host *instance = cmd->device->host;
-	struct NCR5380_hostdata *hostdata = shost_priv(instance);
-	int i;
-	unsigned long flags;
-	struct NCR5380_cmd *ncmd;
-
-	spin_lock_irqsave(&hostdata->lock, flags);
-
-#if (NDEBUG & NDEBUG_ANY)
-	scmd_printk(KERN_INFO, cmd, __func__);
-#endif
-	NCR5380_dprint(NDEBUG_ANY, instance);
-	NCR5380_dprint_phase(NDEBUG_ANY, instance);
-
-	do_reset(instance);
-
-	/* reset NCR registers */
-	NCR5380_write(MODE_REG, MR_BASE);
-	NCR5380_write(TARGET_COMMAND_REG, 0);
-	NCR5380_write(SELECT_ENABLE_REG, 0);
-
-	/* After the reset, there are no more connected or disconnected commands
-	 * and no busy units; so clear the low-level status here to avoid
-	 * conflicts when the mid-level code tries to wake up the affected
-	 * commands!
-	 */
-
-	if (list_del_cmd(&hostdata->unissued, cmd)) {
-		cmd->result = DID_RESET << 16;
-		cmd->scsi_done(cmd);
-	}
-
-	if (hostdata->selecting) {
-		hostdata->selecting->result = DID_RESET << 16;
-		complete_cmd(instance, hostdata->selecting);
-		hostdata->selecting = NULL;
-	}
-
-	list_for_each_entry(ncmd, &hostdata->disconnected, list) {
-		struct scsi_cmnd *cmd = NCR5380_to_scmd(ncmd);
-
-		set_host_byte(cmd, DID_RESET);
-		cmd->scsi_done(cmd);
-	}
-	INIT_LIST_HEAD(&hostdata->disconnected);
-
-	list_for_each_entry(ncmd, &hostdata->autosense, list) {
-		struct scsi_cmnd *cmd = NCR5380_to_scmd(ncmd);
-
-		set_host_byte(cmd, DID_RESET);
-		cmd->scsi_done(cmd);
-	}
-	INIT_LIST_HEAD(&hostdata->autosense);
-
-	if (hostdata->connected) {
-		set_host_byte(hostdata->connected, DID_RESET);
-		complete_cmd(instance, hostdata->connected);
-		hostdata->connected = NULL;
-	}
-
-#ifdef SUPPORT_TAGS
-	free_all_tags(hostdata);
-#endif
-	for (i = 0; i < 8; ++i)
-		hostdata->busy[i] = 0;
-	hostdata->dma_len = 0;
-
-	queue_work(hostdata->work_q, &hostdata->main_task);
-	maybe_release_dma_irq(instance);
-	spin_unlock_irqrestore(&hostdata->lock, flags);
-
-	return SUCCESS;
-}

^ permalink raw reply	[flat|nested] 60+ messages in thread

* [PATCH v4 14/23] ncr5380: Reduce max_lun limit
  2016-03-23 10:10 ` Finn Thain
@ 2016-03-23 10:10   ` Finn Thain
  -1 siblings, 0 replies; 60+ messages in thread
From: Finn Thain @ 2016-03-23 10:10 UTC (permalink / raw)
  To: James E.J. Bottomley, Martin K. Petersen, Michael Schmitz,
	linux-m68k, linux-scsi, linux-kernel
  Cc: Ondrej Zary, Sam Creasey

[-- Attachment #1: ncr5380-max_lun --]
[-- Type: text/plain, Size: 995 bytes --]

The driver has a limit of eight LUs because of the byte-sized bitfield
that is used for busy flags. That means the maximum LUN is 7. The default
is 8.

Signed-off-by: Finn Thain <fthain@telegraphics.com.au>
Tested-by: Michael Schmitz <schmitzmic@gmail.com>
Tested-by: Ondrej Zary <linux@rainbow-software.org>
Reviewed-by: Hannes Reinecke <hare@suse.com>

---

Changed since v1:
- Reduce shost->max_lun limit instead of adding 'MAX_LUN' limit.

---
 drivers/scsi/NCR5380.c |    2 ++
 1 file changed, 2 insertions(+)

Index: linux/drivers/scsi/NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/NCR5380.c	2016-03-23 21:09:53.000000000 +1100
+++ linux/drivers/scsi/NCR5380.c	2016-03-23 21:09:56.000000000 +1100
@@ -488,6 +488,8 @@ static int NCR5380_init(struct Scsi_Host
 	int i;
 	unsigned long deadline;
 
+	instance->max_lun = 7;
+
 	hostdata->host = instance;
 	hostdata->id_mask = 1 << instance->this_id;
 	hostdata->id_higher_mask = 0;

^ permalink raw reply	[flat|nested] 60+ messages in thread

* [PATCH v4 14/23] ncr5380: Reduce max_lun limit
@ 2016-03-23 10:10   ` Finn Thain
  0 siblings, 0 replies; 60+ messages in thread
From: Finn Thain @ 2016-03-23 10:10 UTC (permalink / raw)
  To: James E.J. Bottomley, Martin K. Petersen, Michael Schmitz,
	linux-m68k, linux-scsi, linux-kernel
  Cc: Ondrej Zary, Sam Creasey

[-- Attachment #1: ncr5380-max_lun --]
[-- Type: text/plain, Size: 997 bytes --]

The driver has a limit of eight LUs because of the byte-sized bitfield
that is used for busy flags. That means the maximum LUN is 7. The default
is 8.

Signed-off-by: Finn Thain <fthain@telegraphics.com.au>
Tested-by: Michael Schmitz <schmitzmic@gmail.com>
Tested-by: Ondrej Zary <linux@rainbow-software.org>
Reviewed-by: Hannes Reinecke <hare@suse.com>

---

Changed since v1:
- Reduce shost->max_lun limit instead of adding 'MAX_LUN' limit.

---
 drivers/scsi/NCR5380.c |    2 ++
 1 file changed, 2 insertions(+)

Index: linux/drivers/scsi/NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/NCR5380.c	2016-03-23 21:09:53.000000000 +1100
+++ linux/drivers/scsi/NCR5380.c	2016-03-23 21:09:56.000000000 +1100
@@ -488,6 +488,8 @@ static int NCR5380_init(struct Scsi_Host
 	int i;
 	unsigned long deadline;
 
+	instance->max_lun = 7;
+
 	hostdata->host = instance;
 	hostdata->id_mask = 1 << instance->this_id;
 	hostdata->id_higher_mask = 0;



^ permalink raw reply	[flat|nested] 60+ messages in thread

* [PATCH v4 15/23] dmx3191d: Drop max_sectors limit
  2016-03-23 10:10 ` Finn Thain
@ 2016-03-23 10:10   ` Finn Thain
  -1 siblings, 0 replies; 60+ messages in thread
From: Finn Thain @ 2016-03-23 10:10 UTC (permalink / raw)
  To: James E.J. Bottomley, Martin K. Petersen, Michael Schmitz,
	linux-m68k, linux-scsi, linux-kernel
  Cc: Ondrej Zary, Sam Creasey

[-- Attachment #1: dmx3191d-max_sectors --]
[-- Type: text/plain, Size: 846 bytes --]

The dmx3191d driver is not capable of DMA or PDMA so all transfers
use PIO. Now that large slow PIO transfers periodically stop and call
cond_resched(), the max_sectors limit can go away.

Signed-off-by: Finn Thain <fthain@telegraphics.com.au>
Reviewed-by: Hannes Reinecke <hare@suse.com>

---
 drivers/scsi/dmx3191d.c |    1 -
 1 file changed, 1 deletion(-)

Index: linux/drivers/scsi/dmx3191d.c
===================================================================
--- linux.orig/drivers/scsi/dmx3191d.c	2016-03-23 21:09:47.000000000 +1100
+++ linux/drivers/scsi/dmx3191d.c	2016-03-23 21:09:57.000000000 +1100
@@ -67,7 +67,6 @@ static struct scsi_host_template dmx3191
 	.cmd_per_lun		= 2,
 	.use_clustering		= DISABLE_CLUSTERING,
 	.cmd_size		= NCR5380_CMD_SIZE,
-	.max_sectors		= 128,
 };
 
 static int dmx3191d_probe_one(struct pci_dev *pdev,

^ permalink raw reply	[flat|nested] 60+ messages in thread

* [PATCH v4 15/23] dmx3191d: Drop max_sectors limit
@ 2016-03-23 10:10   ` Finn Thain
  0 siblings, 0 replies; 60+ messages in thread
From: Finn Thain @ 2016-03-23 10:10 UTC (permalink / raw)
  To: James E.J. Bottomley, Martin K. Petersen, Michael Schmitz,
	linux-m68k, linux-scsi, linux-kernel
  Cc: Ondrej Zary, Sam Creasey

[-- Attachment #1: dmx3191d-max_sectors --]
[-- Type: text/plain, Size: 846 bytes --]

The dmx3191d driver is not capable of DMA or PDMA so all transfers
use PIO. Now that large slow PIO transfers periodically stop and call
cond_resched(), the max_sectors limit can go away.

Signed-off-by: Finn Thain <fthain@telegraphics.com.au>
Reviewed-by: Hannes Reinecke <hare@suse.com>

---
 drivers/scsi/dmx3191d.c |    1 -
 1 file changed, 1 deletion(-)

Index: linux/drivers/scsi/dmx3191d.c
===================================================================
--- linux.orig/drivers/scsi/dmx3191d.c	2016-03-23 21:09:47.000000000 +1100
+++ linux/drivers/scsi/dmx3191d.c	2016-03-23 21:09:57.000000000 +1100
@@ -67,7 +67,6 @@ static struct scsi_host_template dmx3191
 	.cmd_per_lun		= 2,
 	.use_clustering		= DISABLE_CLUSTERING,
 	.cmd_size		= NCR5380_CMD_SIZE,
-	.max_sectors		= 128,
 };
 
 static int dmx3191d_probe_one(struct pci_dev *pdev,

^ permalink raw reply	[flat|nested] 60+ messages in thread

* [PATCH v4 16/23] ncr5380: Fix register decoding for debugging
  2016-03-23 10:10 ` Finn Thain
@ 2016-03-23 10:10   ` Finn Thain
  -1 siblings, 0 replies; 60+ messages in thread
From: Finn Thain @ 2016-03-23 10:10 UTC (permalink / raw)
  To: James E.J. Bottomley, Martin K. Petersen, Michael Schmitz,
	linux-m68k, linux-scsi, linux-kernel
  Cc: Ondrej Zary, Sam Creasey

[-- Attachment #1: ncr5380-basr-decoding-dprint --]
[-- Type: text/plain, Size: 3071 bytes --]

Decode all bits in the chip registers. They are all useful at times.
Fix printk severity so that this output can be suppressed along with
the other debugging output.

Signed-off-by: Finn Thain <fthain@telegraphics.com.au>
Reviewed-by: Hannes Reinecke <hare@suse.com>
Tested-by: Michael Schmitz <schmitzmic@gmail.com>
Tested-by: Ondrej Zary <linux@rainbow-software.org>

---
 drivers/scsi/NCR5380.c |   42 +++++++++++++++++++++++++-----------------
 1 file changed, 25 insertions(+), 17 deletions(-)

Index: linux/drivers/scsi/NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/NCR5380.c	2016-03-23 21:09:56.000000000 +1100
+++ linux/drivers/scsi/NCR5380.c	2016-03-23 21:09:57.000000000 +1100
@@ -256,12 +256,20 @@ static struct {
 	{0, NULL}
 },
 basrs[] = {
+	{BASR_END_DMA_TRANSFER, "END OF DMA"},
+	{BASR_DRQ, "DRQ"},
+	{BASR_PARITY_ERROR, "PARITY ERROR"},
+	{BASR_IRQ, "IRQ"},
+	{BASR_PHASE_MATCH, "PHASE MATCH"},
+	{BASR_BUSY_ERROR, "BUSY ERROR"},
 	{BASR_ATN, "ATN"},
 	{BASR_ACK, "ACK"},
 	{0, NULL}
 },
 icrs[] = {
 	{ICR_ASSERT_RST, "ASSERT RST"},
+	{ICR_ARBITRATION_PROGRESS, "ARB. IN PROGRESS"},
+	{ICR_ARBITRATION_LOST, "LOST ARB."},
 	{ICR_ASSERT_ACK, "ASSERT ACK"},
 	{ICR_ASSERT_BSY, "ASSERT BSY"},
 	{ICR_ASSERT_SEL, "ASSERT SEL"},
@@ -270,14 +278,14 @@ icrs[] = {
 	{0, NULL}
 },
 mrs[] = {
-	{MR_BLOCK_DMA_MODE, "MODE BLOCK DMA"},
-	{MR_TARGET, "MODE TARGET"},
-	{MR_ENABLE_PAR_CHECK, "MODE PARITY CHECK"},
-	{MR_ENABLE_PAR_INTR, "MODE PARITY INTR"},
-	{MR_ENABLE_EOP_INTR, "MODE EOP INTR"},
-	{MR_MONITOR_BSY, "MODE MONITOR BSY"},
-	{MR_DMA_MODE, "MODE DMA"},
-	{MR_ARBITRATE, "MODE ARBITRATION"},
+	{MR_BLOCK_DMA_MODE, "BLOCK DMA MODE"},
+	{MR_TARGET, "TARGET"},
+	{MR_ENABLE_PAR_CHECK, "PARITY CHECK"},
+	{MR_ENABLE_PAR_INTR, "PARITY INTR"},
+	{MR_ENABLE_EOP_INTR, "EOP INTR"},
+	{MR_MONITOR_BSY, "MONITOR BSY"},
+	{MR_DMA_MODE, "DMA MODE"},
+	{MR_ARBITRATE, "ARBITRATE"},
 	{0, NULL}
 };
 
@@ -298,23 +306,23 @@ static void NCR5380_print(struct Scsi_Ho
 	icr = NCR5380_read(INITIATOR_COMMAND_REG);
 	basr = NCR5380_read(BUS_AND_STATUS_REG);
 
-	printk("STATUS_REG: %02x ", status);
+	printk(KERN_DEBUG "SR =   0x%02x : ", status);
 	for (i = 0; signals[i].mask; ++i)
 		if (status & signals[i].mask)
-			printk(",%s", signals[i].name);
-	printk("\nBASR: %02x ", basr);
+			printk(KERN_CONT "%s, ", signals[i].name);
+	printk(KERN_CONT "\nBASR = 0x%02x : ", basr);
 	for (i = 0; basrs[i].mask; ++i)
 		if (basr & basrs[i].mask)
-			printk(",%s", basrs[i].name);
-	printk("\nICR: %02x ", icr);
+			printk(KERN_CONT "%s, ", basrs[i].name);
+	printk(KERN_CONT "\nICR =  0x%02x : ", icr);
 	for (i = 0; icrs[i].mask; ++i)
 		if (icr & icrs[i].mask)
-			printk(",%s", icrs[i].name);
-	printk("\nMODE: %02x ", mr);
+			printk(KERN_CONT "%s, ", icrs[i].name);
+	printk(KERN_CONT "\nMR =   0x%02x : ", mr);
 	for (i = 0; mrs[i].mask; ++i)
 		if (mr & mrs[i].mask)
-			printk(",%s", mrs[i].name);
-	printk("\n");
+			printk(KERN_CONT "%s, ", mrs[i].name);
+	printk(KERN_CONT "\n");
 }
 
 static struct {

^ permalink raw reply	[flat|nested] 60+ messages in thread

* [PATCH v4 16/23] ncr5380: Fix register decoding for debugging
@ 2016-03-23 10:10   ` Finn Thain
  0 siblings, 0 replies; 60+ messages in thread
From: Finn Thain @ 2016-03-23 10:10 UTC (permalink / raw)
  To: James E.J. Bottomley, Martin K. Petersen, Michael Schmitz,
	linux-m68k, linux-scsi, linux-kernel
  Cc: Ondrej Zary, Sam Creasey

[-- Attachment #1: ncr5380-basr-decoding-dprint --]
[-- Type: text/plain, Size: 3071 bytes --]

Decode all bits in the chip registers. They are all useful at times.
Fix printk severity so that this output can be suppressed along with
the other debugging output.

Signed-off-by: Finn Thain <fthain@telegraphics.com.au>
Reviewed-by: Hannes Reinecke <hare@suse.com>
Tested-by: Michael Schmitz <schmitzmic@gmail.com>
Tested-by: Ondrej Zary <linux@rainbow-software.org>

---
 drivers/scsi/NCR5380.c |   42 +++++++++++++++++++++++++-----------------
 1 file changed, 25 insertions(+), 17 deletions(-)

Index: linux/drivers/scsi/NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/NCR5380.c	2016-03-23 21:09:56.000000000 +1100
+++ linux/drivers/scsi/NCR5380.c	2016-03-23 21:09:57.000000000 +1100
@@ -256,12 +256,20 @@ static struct {
 	{0, NULL}
 },
 basrs[] = {
+	{BASR_END_DMA_TRANSFER, "END OF DMA"},
+	{BASR_DRQ, "DRQ"},
+	{BASR_PARITY_ERROR, "PARITY ERROR"},
+	{BASR_IRQ, "IRQ"},
+	{BASR_PHASE_MATCH, "PHASE MATCH"},
+	{BASR_BUSY_ERROR, "BUSY ERROR"},
 	{BASR_ATN, "ATN"},
 	{BASR_ACK, "ACK"},
 	{0, NULL}
 },
 icrs[] = {
 	{ICR_ASSERT_RST, "ASSERT RST"},
+	{ICR_ARBITRATION_PROGRESS, "ARB. IN PROGRESS"},
+	{ICR_ARBITRATION_LOST, "LOST ARB."},
 	{ICR_ASSERT_ACK, "ASSERT ACK"},
 	{ICR_ASSERT_BSY, "ASSERT BSY"},
 	{ICR_ASSERT_SEL, "ASSERT SEL"},
@@ -270,14 +278,14 @@ icrs[] = {
 	{0, NULL}
 },
 mrs[] = {
-	{MR_BLOCK_DMA_MODE, "MODE BLOCK DMA"},
-	{MR_TARGET, "MODE TARGET"},
-	{MR_ENABLE_PAR_CHECK, "MODE PARITY CHECK"},
-	{MR_ENABLE_PAR_INTR, "MODE PARITY INTR"},
-	{MR_ENABLE_EOP_INTR, "MODE EOP INTR"},
-	{MR_MONITOR_BSY, "MODE MONITOR BSY"},
-	{MR_DMA_MODE, "MODE DMA"},
-	{MR_ARBITRATE, "MODE ARBITRATION"},
+	{MR_BLOCK_DMA_MODE, "BLOCK DMA MODE"},
+	{MR_TARGET, "TARGET"},
+	{MR_ENABLE_PAR_CHECK, "PARITY CHECK"},
+	{MR_ENABLE_PAR_INTR, "PARITY INTR"},
+	{MR_ENABLE_EOP_INTR, "EOP INTR"},
+	{MR_MONITOR_BSY, "MONITOR BSY"},
+	{MR_DMA_MODE, "DMA MODE"},
+	{MR_ARBITRATE, "ARBITRATE"},
 	{0, NULL}
 };
 
@@ -298,23 +306,23 @@ static void NCR5380_print(struct Scsi_Ho
 	icr = NCR5380_read(INITIATOR_COMMAND_REG);
 	basr = NCR5380_read(BUS_AND_STATUS_REG);
 
-	printk("STATUS_REG: %02x ", status);
+	printk(KERN_DEBUG "SR =   0x%02x : ", status);
 	for (i = 0; signals[i].mask; ++i)
 		if (status & signals[i].mask)
-			printk(",%s", signals[i].name);
-	printk("\nBASR: %02x ", basr);
+			printk(KERN_CONT "%s, ", signals[i].name);
+	printk(KERN_CONT "\nBASR = 0x%02x : ", basr);
 	for (i = 0; basrs[i].mask; ++i)
 		if (basr & basrs[i].mask)
-			printk(",%s", basrs[i].name);
-	printk("\nICR: %02x ", icr);
+			printk(KERN_CONT "%s, ", basrs[i].name);
+	printk(KERN_CONT "\nICR =  0x%02x : ", icr);
 	for (i = 0; icrs[i].mask; ++i)
 		if (icr & icrs[i].mask)
-			printk(",%s", icrs[i].name);
-	printk("\nMODE: %02x ", mr);
+			printk(KERN_CONT "%s, ", icrs[i].name);
+	printk(KERN_CONT "\nMR =   0x%02x : ", mr);
 	for (i = 0; mrs[i].mask; ++i)
 		if (mr & mrs[i].mask)
-			printk(",%s", mrs[i].name);
-	printk("\n");
+			printk(KERN_CONT "%s, ", mrs[i].name);
+	printk(KERN_CONT "\n");
 }
 
 static struct {

^ permalink raw reply	[flat|nested] 60+ messages in thread

* [PATCH v4 17/23] ncr5380: Remove remaining register storage qualifiers
  2016-03-23 10:10 ` Finn Thain
@ 2016-03-23 10:10   ` Finn Thain
  -1 siblings, 0 replies; 60+ messages in thread
From: Finn Thain @ 2016-03-23 10:10 UTC (permalink / raw)
  To: James E.J. Bottomley, Martin K. Petersen, Michael Schmitz,
	linux-m68k, linux-scsi, linux-kernel
  Cc: Ondrej Zary, Sam Creasey

[-- Attachment #1: ncr5380-remove-register-storage-qualifier --]
[-- Type: text/plain, Size: 911 bytes --]

Signed-off-by: Finn Thain <fthain@telegraphics.com.au>
Reviewed-by: Hannes Reinecke <hare@suse.com>
Tested-by: Michael Schmitz <schmitzmic@gmail.com>
Tested-by: Ondrej Zary <linux@rainbow-software.org>

---
 drivers/scsi/NCR5380.c |    6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

Index: linux/drivers/scsi/NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/NCR5380.c	2016-03-23 21:09:57.000000000 +1100
+++ linux/drivers/scsi/NCR5380.c	2016-03-23 21:09:59.000000000 +1100
@@ -1555,9 +1555,9 @@ static int NCR5380_transfer_dma(struct S
 				unsigned char **data)
 {
 	struct NCR5380_hostdata *hostdata = shost_priv(instance);
-	register int c = *count;
-	register unsigned char p = *phase;
-	register unsigned char *d = *data;
+	int c = *count;
+	unsigned char p = *phase;
+	unsigned char *d = *data;
 	unsigned char tmp;
 	int result = 0;
 

^ permalink raw reply	[flat|nested] 60+ messages in thread

* [PATCH v4 17/23] ncr5380: Remove remaining register storage qualifiers
@ 2016-03-23 10:10   ` Finn Thain
  0 siblings, 0 replies; 60+ messages in thread
From: Finn Thain @ 2016-03-23 10:10 UTC (permalink / raw)
  To: James E.J. Bottomley, Martin K. Petersen, Michael Schmitz,
	linux-m68k, linux-scsi, linux-kernel
  Cc: Ondrej Zary, Sam Creasey

[-- Attachment #1: ncr5380-remove-register-storage-qualifier --]
[-- Type: text/plain, Size: 911 bytes --]

Signed-off-by: Finn Thain <fthain@telegraphics.com.au>
Reviewed-by: Hannes Reinecke <hare@suse.com>
Tested-by: Michael Schmitz <schmitzmic@gmail.com>
Tested-by: Ondrej Zary <linux@rainbow-software.org>

---
 drivers/scsi/NCR5380.c |    6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

Index: linux/drivers/scsi/NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/NCR5380.c	2016-03-23 21:09:57.000000000 +1100
+++ linux/drivers/scsi/NCR5380.c	2016-03-23 21:09:59.000000000 +1100
@@ -1555,9 +1555,9 @@ static int NCR5380_transfer_dma(struct S
 				unsigned char **data)
 {
 	struct NCR5380_hostdata *hostdata = shost_priv(instance);
-	register int c = *count;
-	register unsigned char p = *phase;
-	register unsigned char *d = *data;
+	int c = *count;
+	unsigned char p = *phase;
+	unsigned char *d = *data;
 	unsigned char tmp;
 	int result = 0;
 

^ permalink raw reply	[flat|nested] 60+ messages in thread

* [PATCH v4 18/23] ncr5380: Remove DONT_USE_INTR and AUTOPROBE_IRQ macros
  2016-03-23 10:10 ` Finn Thain
  (?)
@ 2016-03-23 10:10   ` Finn Thain
  -1 siblings, 0 replies; 60+ messages in thread
From: Finn Thain @ 2016-03-23 10:10 UTC (permalink / raw)
  To: James E.J. Bottomley, Martin K. Petersen, Michael Schmitz,
	linux-m68k, linux-scsi, linux-kernel, Russell King,
	linux-arm-kernel
  Cc: Ondrej Zary, Sam Creasey

[-- Attachment #1: ncr5380-remove-DONT_USE_INTR-and-AUTOPROBE_IRQ-macros --]
[-- Type: text/plain, Size: 6727 bytes --]

Signed-off-by: Finn Thain <fthain@telegraphics.com.au>
Reviewed-by: Hannes Reinecke <hare@suse.com>
Tested-by: Michael Schmitz <schmitzmic@gmail.com>
Tested-by: Ondrej Zary <linux@rainbow-software.org>

---
 drivers/scsi/NCR5380.c   |   12 +-----------
 drivers/scsi/NCR5380.h   |    4 ----
 drivers/scsi/arm/oak.c   |    2 --
 drivers/scsi/dmx3191d.c  |    2 --
 drivers/scsi/dtc.c       |   12 +++---------
 drivers/scsi/g_NCR5380.c |    2 --
 drivers/scsi/pas16.c     |    1 -
 drivers/scsi/t128.c      |    1 -
 8 files changed, 4 insertions(+), 32 deletions(-)

Index: linux/drivers/scsi/NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/NCR5380.c	2016-03-23 21:09:59.000000000 +1100
+++ linux/drivers/scsi/NCR5380.c	2016-03-23 21:10:00.000000000 +1100
@@ -106,9 +106,6 @@
  * DIFFERENTIAL - if defined, NCR53c81 chips will use external differential
  * transceivers.
  *
- * DONT_USE_INTR - if defined, never use interrupts, even if we probe or
- * override-configure an IRQ.
- *
  * PSEUDO_DMA - if defined, PSEUDO DMA is used during the data transfer phases.
  *
  * REAL_DMA - if defined, REAL DMA is used during the data transfer phases.
@@ -464,9 +461,6 @@ static void prepare_info(struct Scsi_Hos
 	         hostdata->flags & FLAG_DMA_FIXUP     ? "DMA_FIXUP "     : "",
 	         hostdata->flags & FLAG_NO_PSEUDO_DMA ? "NO_PSEUDO_DMA " : "",
 	         hostdata->flags & FLAG_TOSHIBA_DELAY ? "TOSHIBA_DELAY "  : "",
-#ifdef AUTOPROBE_IRQ
-	         "AUTOPROBE_IRQ "
-#endif
 #ifdef DIFFERENTIAL
 	         "DIFFERENTIAL "
 #endif
@@ -915,8 +909,6 @@ static void NCR5380_dma_complete(struct
 	}
 }
 
-#ifndef DONT_USE_INTR
-
 /**
  * NCR5380_intr - generic NCR5380 irq handler
  * @irq: interrupt number
@@ -951,7 +943,7 @@ static void NCR5380_dma_complete(struct
  * the Busy Monitor interrupt is enabled together with DMA Mode.
  */
 
-static irqreturn_t NCR5380_intr(int irq, void *dev_id)
+static irqreturn_t __maybe_unused NCR5380_intr(int irq, void *dev_id)
 {
 	struct Scsi_Host *instance = dev_id;
 	struct NCR5380_hostdata *hostdata = shost_priv(instance);
@@ -1020,8 +1012,6 @@ static irqreturn_t NCR5380_intr(int irq,
 	return IRQ_RETVAL(handled);
 }
 
-#endif
-
 /*
  * Function : int NCR5380_select(struct Scsi_Host *instance,
  * struct scsi_cmnd *cmd)
Index: linux/drivers/scsi/NCR5380.h
===================================================================
--- linux.orig/drivers/scsi/NCR5380.h	2016-03-23 21:09:53.000000000 +1100
+++ linux/drivers/scsi/NCR5380.h	2016-03-23 21:10:00.000000000 +1100
@@ -280,16 +280,12 @@ static void NCR5380_print(struct Scsi_Ho
 #define NCR5380_dprint_phase(flg, arg) do {} while (0)
 #endif
 
-#if defined(AUTOPROBE_IRQ)
 static int NCR5380_probe_irq(struct Scsi_Host *instance, int possible);
-#endif
 static int NCR5380_init(struct Scsi_Host *instance, int flags);
 static int NCR5380_maybe_reset_bus(struct Scsi_Host *);
 static void NCR5380_exit(struct Scsi_Host *instance);
 static void NCR5380_information_transfer(struct Scsi_Host *instance);
-#ifndef DONT_USE_INTR
 static irqreturn_t NCR5380_intr(int irq, void *dev_id);
-#endif
 static void NCR5380_main(struct work_struct *work);
 static const char *NCR5380_info(struct Scsi_Host *instance);
 static void NCR5380_reselect(struct Scsi_Host *instance);
Index: linux/drivers/scsi/arm/oak.c
===================================================================
--- linux.orig/drivers/scsi/arm/oak.c	2016-03-23 21:09:47.000000000 +1100
+++ linux/drivers/scsi/arm/oak.c	2016-03-23 21:10:00.000000000 +1100
@@ -14,8 +14,6 @@
 
 #include <scsi/scsi_host.h>
 
-#define DONT_USE_INTR
-
 #define priv(host)			((struct NCR5380_hostdata *)(host)->hostdata)
 
 #define NCR5380_read(reg) \
Index: linux/drivers/scsi/dmx3191d.c
===================================================================
--- linux.orig/drivers/scsi/dmx3191d.c	2016-03-23 21:09:57.000000000 +1100
+++ linux/drivers/scsi/dmx3191d.c	2016-03-23 21:10:00.000000000 +1100
@@ -34,8 +34,6 @@
  * Definitions for the generic 5380 driver.
  */
 
-#define DONT_USE_INTR
-
 #define NCR5380_read(reg)		inb(instance->io_port + reg)
 #define NCR5380_write(reg, value)	outb(value, instance->io_port + reg)
 
Index: linux/drivers/scsi/dtc.c
===================================================================
--- linux.orig/drivers/scsi/dtc.c	2016-03-23 21:09:47.000000000 +1100
+++ linux/drivers/scsi/dtc.c	2016-03-23 21:10:00.000000000 +1100
@@ -1,5 +1,3 @@
-#define DONT_USE_INTR
-
 /*
  * DTC 3180/3280 driver, by
  *	Ray Van Tassle	rayvt@comm.mot.com
@@ -53,7 +51,6 @@
 #include <scsi/scsi_host.h>
 
 #include "dtc.h"
-#define AUTOPROBE_IRQ
 #include "NCR5380.h"
 
 /*
@@ -243,9 +240,10 @@ found:
 		if (instance->irq == 255)
 			instance->irq = NO_IRQ;
 
-#ifndef DONT_USE_INTR
 		/* With interrupts enabled, it will sometimes hang when doing heavy
 		 * reads. So better not enable them until I finger it out. */
+		instance->irq = NO_IRQ;
+
 		if (instance->irq != NO_IRQ)
 			if (request_irq(instance->irq, dtc_intr, 0,
 					"dtc", instance)) {
@@ -257,11 +255,7 @@ found:
 			printk(KERN_WARNING "scsi%d : interrupts not enabled. for better interactive performance,\n", instance->host_no);
 			printk(KERN_WARNING "scsi%d : please jumper the board for a free IRQ.\n", instance->host_no);
 		}
-#else
-		if (instance->irq != NO_IRQ)
-			printk(KERN_WARNING "scsi%d : interrupts not used. Might as well not jumper it.\n", instance->host_no);
-		instance->irq = NO_IRQ;
-#endif
+
 		dprintk(NDEBUG_INIT, "scsi%d : irq = %d\n",
 		        instance->host_no, instance->irq);
 
Index: linux/drivers/scsi/g_NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/g_NCR5380.c	2016-03-23 21:09:47.000000000 +1100
+++ linux/drivers/scsi/g_NCR5380.c	2016-03-23 21:10:00.000000000 +1100
@@ -56,8 +56,6 @@
  *     
  */
 
-#define AUTOPROBE_IRQ
-
 #include <asm/io.h>
 #include <linux/blkdev.h>
 #include <linux/module.h>
Index: linux/drivers/scsi/pas16.c
===================================================================
--- linux.orig/drivers/scsi/pas16.c	2016-03-23 21:09:47.000000000 +1100
+++ linux/drivers/scsi/pas16.c	2016-03-23 21:10:00.000000000 +1100
@@ -75,7 +75,6 @@
 
 #include <scsi/scsi_host.h>
 #include "pas16.h"
-#define AUTOPROBE_IRQ
 #include "NCR5380.h"
 
 
Index: linux/drivers/scsi/t128.c
===================================================================
--- linux.orig/drivers/scsi/t128.c	2016-03-23 21:09:47.000000000 +1100
+++ linux/drivers/scsi/t128.c	2016-03-23 21:10:00.000000000 +1100
@@ -74,7 +74,6 @@
 
 #include <scsi/scsi_host.h>
 #include "t128.h"
-#define AUTOPROBE_IRQ
 #include "NCR5380.h"
 
 static struct override {

^ permalink raw reply	[flat|nested] 60+ messages in thread

* [PATCH v4 18/23] ncr5380: Remove DONT_USE_INTR and AUTOPROBE_IRQ macros
@ 2016-03-23 10:10   ` Finn Thain
  0 siblings, 0 replies; 60+ messages in thread
From: Finn Thain @ 2016-03-23 10:10 UTC (permalink / raw)
  To: James E.J. Bottomley, Martin K. Petersen, Michael Schmitz,
	linux-m68k, linux-scsi, linux-kernel, Russell King,
	linux-arm-kernel
  Cc: Ondrej Zary, Sam Creasey

[-- Attachment #1: ncr5380-remove-DONT_USE_INTR-and-AUTOPROBE_IRQ-macros --]
[-- Type: text/plain, Size: 6727 bytes --]

Signed-off-by: Finn Thain <fthain@telegraphics.com.au>
Reviewed-by: Hannes Reinecke <hare@suse.com>
Tested-by: Michael Schmitz <schmitzmic@gmail.com>
Tested-by: Ondrej Zary <linux@rainbow-software.org>

---
 drivers/scsi/NCR5380.c   |   12 +-----------
 drivers/scsi/NCR5380.h   |    4 ----
 drivers/scsi/arm/oak.c   |    2 --
 drivers/scsi/dmx3191d.c  |    2 --
 drivers/scsi/dtc.c       |   12 +++---------
 drivers/scsi/g_NCR5380.c |    2 --
 drivers/scsi/pas16.c     |    1 -
 drivers/scsi/t128.c      |    1 -
 8 files changed, 4 insertions(+), 32 deletions(-)

Index: linux/drivers/scsi/NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/NCR5380.c	2016-03-23 21:09:59.000000000 +1100
+++ linux/drivers/scsi/NCR5380.c	2016-03-23 21:10:00.000000000 +1100
@@ -106,9 +106,6 @@
  * DIFFERENTIAL - if defined, NCR53c81 chips will use external differential
  * transceivers.
  *
- * DONT_USE_INTR - if defined, never use interrupts, even if we probe or
- * override-configure an IRQ.
- *
  * PSEUDO_DMA - if defined, PSEUDO DMA is used during the data transfer phases.
  *
  * REAL_DMA - if defined, REAL DMA is used during the data transfer phases.
@@ -464,9 +461,6 @@ static void prepare_info(struct Scsi_Hos
 	         hostdata->flags & FLAG_DMA_FIXUP     ? "DMA_FIXUP "     : "",
 	         hostdata->flags & FLAG_NO_PSEUDO_DMA ? "NO_PSEUDO_DMA " : "",
 	         hostdata->flags & FLAG_TOSHIBA_DELAY ? "TOSHIBA_DELAY "  : "",
-#ifdef AUTOPROBE_IRQ
-	         "AUTOPROBE_IRQ "
-#endif
 #ifdef DIFFERENTIAL
 	         "DIFFERENTIAL "
 #endif
@@ -915,8 +909,6 @@ static void NCR5380_dma_complete(struct
 	}
 }
 
-#ifndef DONT_USE_INTR
-
 /**
  * NCR5380_intr - generic NCR5380 irq handler
  * @irq: interrupt number
@@ -951,7 +943,7 @@ static void NCR5380_dma_complete(struct
  * the Busy Monitor interrupt is enabled together with DMA Mode.
  */
 
-static irqreturn_t NCR5380_intr(int irq, void *dev_id)
+static irqreturn_t __maybe_unused NCR5380_intr(int irq, void *dev_id)
 {
 	struct Scsi_Host *instance = dev_id;
 	struct NCR5380_hostdata *hostdata = shost_priv(instance);
@@ -1020,8 +1012,6 @@ static irqreturn_t NCR5380_intr(int irq,
 	return IRQ_RETVAL(handled);
 }
 
-#endif
-
 /*
  * Function : int NCR5380_select(struct Scsi_Host *instance,
  * struct scsi_cmnd *cmd)
Index: linux/drivers/scsi/NCR5380.h
===================================================================
--- linux.orig/drivers/scsi/NCR5380.h	2016-03-23 21:09:53.000000000 +1100
+++ linux/drivers/scsi/NCR5380.h	2016-03-23 21:10:00.000000000 +1100
@@ -280,16 +280,12 @@ static void NCR5380_print(struct Scsi_Ho
 #define NCR5380_dprint_phase(flg, arg) do {} while (0)
 #endif
 
-#if defined(AUTOPROBE_IRQ)
 static int NCR5380_probe_irq(struct Scsi_Host *instance, int possible);
-#endif
 static int NCR5380_init(struct Scsi_Host *instance, int flags);
 static int NCR5380_maybe_reset_bus(struct Scsi_Host *);
 static void NCR5380_exit(struct Scsi_Host *instance);
 static void NCR5380_information_transfer(struct Scsi_Host *instance);
-#ifndef DONT_USE_INTR
 static irqreturn_t NCR5380_intr(int irq, void *dev_id);
-#endif
 static void NCR5380_main(struct work_struct *work);
 static const char *NCR5380_info(struct Scsi_Host *instance);
 static void NCR5380_reselect(struct Scsi_Host *instance);
Index: linux/drivers/scsi/arm/oak.c
===================================================================
--- linux.orig/drivers/scsi/arm/oak.c	2016-03-23 21:09:47.000000000 +1100
+++ linux/drivers/scsi/arm/oak.c	2016-03-23 21:10:00.000000000 +1100
@@ -14,8 +14,6 @@
 
 #include <scsi/scsi_host.h>
 
-#define DONT_USE_INTR
-
 #define priv(host)			((struct NCR5380_hostdata *)(host)->hostdata)
 
 #define NCR5380_read(reg) \
Index: linux/drivers/scsi/dmx3191d.c
===================================================================
--- linux.orig/drivers/scsi/dmx3191d.c	2016-03-23 21:09:57.000000000 +1100
+++ linux/drivers/scsi/dmx3191d.c	2016-03-23 21:10:00.000000000 +1100
@@ -34,8 +34,6 @@
  * Definitions for the generic 5380 driver.
  */
 
-#define DONT_USE_INTR
-
 #define NCR5380_read(reg)		inb(instance->io_port + reg)
 #define NCR5380_write(reg, value)	outb(value, instance->io_port + reg)
 
Index: linux/drivers/scsi/dtc.c
===================================================================
--- linux.orig/drivers/scsi/dtc.c	2016-03-23 21:09:47.000000000 +1100
+++ linux/drivers/scsi/dtc.c	2016-03-23 21:10:00.000000000 +1100
@@ -1,5 +1,3 @@
-#define DONT_USE_INTR
-
 /*
  * DTC 3180/3280 driver, by
  *	Ray Van Tassle	rayvt@comm.mot.com
@@ -53,7 +51,6 @@
 #include <scsi/scsi_host.h>
 
 #include "dtc.h"
-#define AUTOPROBE_IRQ
 #include "NCR5380.h"
 
 /*
@@ -243,9 +240,10 @@ found:
 		if (instance->irq == 255)
 			instance->irq = NO_IRQ;
 
-#ifndef DONT_USE_INTR
 		/* With interrupts enabled, it will sometimes hang when doing heavy
 		 * reads. So better not enable them until I finger it out. */
+		instance->irq = NO_IRQ;
+
 		if (instance->irq != NO_IRQ)
 			if (request_irq(instance->irq, dtc_intr, 0,
 					"dtc", instance)) {
@@ -257,11 +255,7 @@ found:
 			printk(KERN_WARNING "scsi%d : interrupts not enabled. for better interactive performance,\n", instance->host_no);
 			printk(KERN_WARNING "scsi%d : please jumper the board for a free IRQ.\n", instance->host_no);
 		}
-#else
-		if (instance->irq != NO_IRQ)
-			printk(KERN_WARNING "scsi%d : interrupts not used. Might as well not jumper it.\n", instance->host_no);
-		instance->irq = NO_IRQ;
-#endif
+
 		dprintk(NDEBUG_INIT, "scsi%d : irq = %d\n",
 		        instance->host_no, instance->irq);
 
Index: linux/drivers/scsi/g_NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/g_NCR5380.c	2016-03-23 21:09:47.000000000 +1100
+++ linux/drivers/scsi/g_NCR5380.c	2016-03-23 21:10:00.000000000 +1100
@@ -56,8 +56,6 @@
  *     
  */
 
-#define AUTOPROBE_IRQ
-
 #include <asm/io.h>
 #include <linux/blkdev.h>
 #include <linux/module.h>
Index: linux/drivers/scsi/pas16.c
===================================================================
--- linux.orig/drivers/scsi/pas16.c	2016-03-23 21:09:47.000000000 +1100
+++ linux/drivers/scsi/pas16.c	2016-03-23 21:10:00.000000000 +1100
@@ -75,7 +75,6 @@
 
 #include <scsi/scsi_host.h>
 #include "pas16.h"
-#define AUTOPROBE_IRQ
 #include "NCR5380.h"
 
 
Index: linux/drivers/scsi/t128.c
===================================================================
--- linux.orig/drivers/scsi/t128.c	2016-03-23 21:09:47.000000000 +1100
+++ linux/drivers/scsi/t128.c	2016-03-23 21:10:00.000000000 +1100
@@ -74,7 +74,6 @@
 
 #include <scsi/scsi_host.h>
 #include "t128.h"
-#define AUTOPROBE_IRQ
 #include "NCR5380.h"
 
 static struct override {

^ permalink raw reply	[flat|nested] 60+ messages in thread

* [PATCH v4 18/23] ncr5380: Remove DONT_USE_INTR and AUTOPROBE_IRQ macros
@ 2016-03-23 10:10   ` Finn Thain
  0 siblings, 0 replies; 60+ messages in thread
From: Finn Thain @ 2016-03-23 10:10 UTC (permalink / raw)
  To: linux-arm-kernel

An embedded and charset-unspecified text was scrubbed...
Name: ncr5380-remove-DONT_USE_INTR-and-AUTOPROBE_IRQ-macros
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20160323/15d611aa/attachment.ksh>

^ permalink raw reply	[flat|nested] 60+ messages in thread

* [PATCH v4 19/23] ncr5380: Update usage documentation
  2016-03-23 10:10 ` Finn Thain
@ 2016-03-23 10:10   ` Finn Thain
  -1 siblings, 0 replies; 60+ messages in thread
From: Finn Thain @ 2016-03-23 10:10 UTC (permalink / raw)
  To: James E.J. Bottomley, Martin K. Petersen, Michael Schmitz,
	linux-m68k, linux-scsi, linux-kernel, Jonathan Corbet, linux-doc
  Cc: Ondrej Zary, Sam Creasey

[-- Attachment #1: ncr5380-update-documentation --]
[-- Type: text/plain, Size: 5594 bytes --]

Update kernel parameter documentation for atari_scsi, mac_scsi and
g_NCR5380 drivers. Remove duplication.

Signed-off-by: Finn Thain <fthain@telegraphics.com.au>
Reviewed-by: Hannes Reinecke <hare@suse.com>

---
 Documentation/scsi/g_NCR5380.txt       |   17 ++++++---------
 Documentation/scsi/scsi-parameters.txt |   11 +++++++---
 drivers/scsi/g_NCR5380.c               |   36 ---------------------------------
 3 files changed, 16 insertions(+), 48 deletions(-)

Index: linux/Documentation/scsi/scsi-parameters.txt
===================================================================
--- linux.orig/Documentation/scsi/scsi-parameters.txt	2016-03-23 21:05:15.000000000 +1100
+++ linux/Documentation/scsi/scsi-parameters.txt	2016-03-23 21:10:02.000000000 +1100
@@ -27,13 +27,15 @@ parameters may be changed at runtime by
 	aic79xx=	[HW,SCSI]
 			See Documentation/scsi/aic79xx.txt.
 
-	atascsi=	[HW,SCSI] Atari SCSI
+	atascsi=	[HW,SCSI]
+			See drivers/scsi/atari_scsi.c.
 
 	BusLogic=	[HW,SCSI]
 			See drivers/scsi/BusLogic.c, comment before function
 			BusLogic_ParseDriverOptions().
 
 	dtc3181e=	[HW,SCSI]
+			See Documentation/scsi/g_NCR5380.txt.
 
 	eata=		[HW,SCSI]
 
@@ -51,8 +53,8 @@ parameters may be changed at runtime by
 	ips=		[HW,SCSI] Adaptec / IBM ServeRAID controller
 			See header of drivers/scsi/ips.c.
 
-	mac5380=	[HW,SCSI] Format:
-			<can_queue>,<cmd_per_lun>,<sg_tablesize>,<hostid>,<use_tags>
+	mac5380=	[HW,SCSI]
+			See drivers/scsi/mac_scsi.c.
 
 	max_luns=	[SCSI] Maximum number of LUNs to probe.
 			Should be between 1 and 2^32-1.
@@ -65,10 +67,13 @@ parameters may be changed at runtime by
 			See header of drivers/scsi/NCR_D700.c.
 
 	ncr5380=	[HW,SCSI]
+			See Documentation/scsi/g_NCR5380.txt.
 
 	ncr53c400=	[HW,SCSI]
+			See Documentation/scsi/g_NCR5380.txt.
 
 	ncr53c400a=	[HW,SCSI]
+			See Documentation/scsi/g_NCR5380.txt.
 
 	ncr53c406a=	[HW,SCSI]
 
Index: linux/Documentation/scsi/g_NCR5380.txt
===================================================================
--- linux.orig/Documentation/scsi/g_NCR5380.txt	2016-03-23 21:05:15.000000000 +1100
+++ linux/Documentation/scsi/g_NCR5380.txt	2016-03-23 21:10:02.000000000 +1100
@@ -23,11 +23,10 @@ supported by the driver.
 
 If the default configuration does not work for you, you can use the kernel
 command lines (eg using the lilo append command):
-	ncr5380=port,irq,dma
-	ncr53c400=port,irq
-or
-	ncr5380=base,irq,dma
-	ncr53c400=base,irq
+	ncr5380=addr,irq
+	ncr53c400=addr,irq
+	ncr53c400a=addr,irq
+	dtc3181e=addr,irq
 
 The driver does not probe for any addresses or ports other than those in
 the OVERRIDE or given to the kernel as above.
@@ -36,19 +35,17 @@ This driver provides some information on
 /proc/scsi/g_NCR5380/x where x is the scsi card number as detected at boot
 time. More info to come in the future.
 
-When NCR53c400 support is compiled in, BIOS parameters will be returned by
-the driver (the raw 5380 driver does not and I don't plan to fiddle with
-it!).
-
 This driver works as a module.
 When included as a module, parameters can be passed on the insmod/modprobe
 command line:
   ncr_irq=xx   the interrupt
   ncr_addr=xx  the port or base address (for port or memory
                mapped, resp.)
-  ncr_dma=xx   the DMA
   ncr_5380=1   to set up for a NCR5380 board
   ncr_53c400=1 to set up for a NCR53C400 board
+  ncr_53c400a=1 to set up for a NCR53C400A board
+  dtc_3181e=1  to set up for a Domex Technology Corp 3181E board
+  hp_c2502=1   to set up for a Hewlett Packard C2502 board
 e.g.
 modprobe g_NCR5380 ncr_irq=5 ncr_addr=0x350 ncr_5380=1
   for a port mapped NCR5380 board or
Index: linux/drivers/scsi/g_NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/g_NCR5380.c	2016-03-23 21:10:00.000000000 +1100
+++ linux/drivers/scsi/g_NCR5380.c	2016-03-23 21:10:02.000000000 +1100
@@ -18,42 +18,8 @@
  *
  * Added ISAPNP support for DTC436 adapters,
  * Thomas Sailer, sailer@ife.ee.ethz.ch
- */
-
-/* 
- * TODO : flesh out DMA support, find some one actually using this (I have
- * 	a memory mapped Trantor board that works fine)
- */
-
-/*
- * The card is detected and initialized in one of several ways : 
- * 1.  With command line overrides - NCR5380=port,irq may be 
- *     used on the LILO command line to override the defaults.
- *
- * 2.  With the GENERIC_NCR5380_OVERRIDE compile time define.  This is 
- *     specified as an array of address, irq, dma, board tuples.  Ie, for
- *     one board at 0x350, IRQ5, no dma, I could say  
- *     -DGENERIC_NCR5380_OVERRIDE={{0xcc000, 5, DMA_NONE, BOARD_NCR5380}}
- * 
- * -1 should be specified for no or DMA interrupt, -2 to autoprobe for an 
- * 	IRQ line if overridden on the command line.
  *
- * 3.  When included as a module, with arguments passed on the command line:
- *         ncr_irq=xx	the interrupt
- *         ncr_addr=xx  the port or base address (for port or memory
- *              	mapped, resp.)
- *         ncr_dma=xx	the DMA
- *         ncr_5380=1	to set up for a NCR5380 board
- *         ncr_53c400=1	to set up for a NCR53C400 board
- *     e.g.
- *     modprobe g_NCR5380 ncr_irq=5 ncr_addr=0x350 ncr_5380=1
- *       for a port mapped NCR5380 board or
- *     modprobe g_NCR5380 ncr_irq=255 ncr_addr=0xc8000 ncr_53c400=1
- *       for a memory mapped NCR53C400 board with interrupts disabled.
- * 
- * 255 should be specified for no or DMA interrupt, 254 to autoprobe for an 
- * 	IRQ line if overridden on the command line.
- *     
+ * See Documentation/scsi/g_NCR5380.txt for more info.
  */
 
 #include <asm/io.h>

^ permalink raw reply	[flat|nested] 60+ messages in thread

* [PATCH v4 19/23] ncr5380: Update usage documentation
@ 2016-03-23 10:10   ` Finn Thain
  0 siblings, 0 replies; 60+ messages in thread
From: Finn Thain @ 2016-03-23 10:10 UTC (permalink / raw)
  To: James E.J. Bottomley, Martin K. Petersen, Michael Schmitz,
	linux-m68k, linux-scsi, linux-kernel, Jonathan Corbet, linux-doc
  Cc: Ondrej Zary, Sam Creasey

[-- Attachment #1: ncr5380-update-documentation --]
[-- Type: text/plain, Size: 5596 bytes --]

Update kernel parameter documentation for atari_scsi, mac_scsi and
g_NCR5380 drivers. Remove duplication.

Signed-off-by: Finn Thain <fthain@telegraphics.com.au>
Reviewed-by: Hannes Reinecke <hare@suse.com>

---
 Documentation/scsi/g_NCR5380.txt       |   17 ++++++---------
 Documentation/scsi/scsi-parameters.txt |   11 +++++++---
 drivers/scsi/g_NCR5380.c               |   36 ---------------------------------
 3 files changed, 16 insertions(+), 48 deletions(-)

Index: linux/Documentation/scsi/scsi-parameters.txt
===================================================================
--- linux.orig/Documentation/scsi/scsi-parameters.txt	2016-03-23 21:05:15.000000000 +1100
+++ linux/Documentation/scsi/scsi-parameters.txt	2016-03-23 21:10:02.000000000 +1100
@@ -27,13 +27,15 @@ parameters may be changed at runtime by
 	aic79xx=	[HW,SCSI]
 			See Documentation/scsi/aic79xx.txt.
 
-	atascsi=	[HW,SCSI] Atari SCSI
+	atascsi=	[HW,SCSI]
+			See drivers/scsi/atari_scsi.c.
 
 	BusLogic=	[HW,SCSI]
 			See drivers/scsi/BusLogic.c, comment before function
 			BusLogic_ParseDriverOptions().
 
 	dtc3181e=	[HW,SCSI]
+			See Documentation/scsi/g_NCR5380.txt.
 
 	eata=		[HW,SCSI]
 
@@ -51,8 +53,8 @@ parameters may be changed at runtime by
 	ips=		[HW,SCSI] Adaptec / IBM ServeRAID controller
 			See header of drivers/scsi/ips.c.
 
-	mac5380=	[HW,SCSI] Format:
-			<can_queue>,<cmd_per_lun>,<sg_tablesize>,<hostid>,<use_tags>
+	mac5380=	[HW,SCSI]
+			See drivers/scsi/mac_scsi.c.
 
 	max_luns=	[SCSI] Maximum number of LUNs to probe.
 			Should be between 1 and 2^32-1.
@@ -65,10 +67,13 @@ parameters may be changed at runtime by
 			See header of drivers/scsi/NCR_D700.c.
 
 	ncr5380=	[HW,SCSI]
+			See Documentation/scsi/g_NCR5380.txt.
 
 	ncr53c400=	[HW,SCSI]
+			See Documentation/scsi/g_NCR5380.txt.
 
 	ncr53c400a=	[HW,SCSI]
+			See Documentation/scsi/g_NCR5380.txt.
 
 	ncr53c406a=	[HW,SCSI]
 
Index: linux/Documentation/scsi/g_NCR5380.txt
===================================================================
--- linux.orig/Documentation/scsi/g_NCR5380.txt	2016-03-23 21:05:15.000000000 +1100
+++ linux/Documentation/scsi/g_NCR5380.txt	2016-03-23 21:10:02.000000000 +1100
@@ -23,11 +23,10 @@ supported by the driver.
 
 If the default configuration does not work for you, you can use the kernel
 command lines (eg using the lilo append command):
-	ncr5380=port,irq,dma
-	ncr53c400=port,irq
-or
-	ncr5380=base,irq,dma
-	ncr53c400=base,irq
+	ncr5380=addr,irq
+	ncr53c400=addr,irq
+	ncr53c400a=addr,irq
+	dtc3181e=addr,irq
 
 The driver does not probe for any addresses or ports other than those in
 the OVERRIDE or given to the kernel as above.
@@ -36,19 +35,17 @@ This driver provides some information on
 /proc/scsi/g_NCR5380/x where x is the scsi card number as detected at boot
 time. More info to come in the future.
 
-When NCR53c400 support is compiled in, BIOS parameters will be returned by
-the driver (the raw 5380 driver does not and I don't plan to fiddle with
-it!).
-
 This driver works as a module.
 When included as a module, parameters can be passed on the insmod/modprobe
 command line:
   ncr_irq=xx   the interrupt
   ncr_addr=xx  the port or base address (for port or memory
                mapped, resp.)
-  ncr_dma=xx   the DMA
   ncr_5380=1   to set up for a NCR5380 board
   ncr_53c400=1 to set up for a NCR53C400 board
+  ncr_53c400a=1 to set up for a NCR53C400A board
+  dtc_3181e=1  to set up for a Domex Technology Corp 3181E board
+  hp_c2502=1   to set up for a Hewlett Packard C2502 board
 e.g.
 modprobe g_NCR5380 ncr_irq=5 ncr_addr=0x350 ncr_5380=1
   for a port mapped NCR5380 board or
Index: linux/drivers/scsi/g_NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/g_NCR5380.c	2016-03-23 21:10:00.000000000 +1100
+++ linux/drivers/scsi/g_NCR5380.c	2016-03-23 21:10:02.000000000 +1100
@@ -18,42 +18,8 @@
  *
  * Added ISAPNP support for DTC436 adapters,
  * Thomas Sailer, sailer@ife.ee.ethz.ch
- */
-
-/* 
- * TODO : flesh out DMA support, find some one actually using this (I have
- * 	a memory mapped Trantor board that works fine)
- */
-
-/*
- * The card is detected and initialized in one of several ways : 
- * 1.  With command line overrides - NCR5380=port,irq may be 
- *     used on the LILO command line to override the defaults.
- *
- * 2.  With the GENERIC_NCR5380_OVERRIDE compile time define.  This is 
- *     specified as an array of address, irq, dma, board tuples.  Ie, for
- *     one board at 0x350, IRQ5, no dma, I could say  
- *     -DGENERIC_NCR5380_OVERRIDE={{0xcc000, 5, DMA_NONE, BOARD_NCR5380}}
- * 
- * -1 should be specified for no or DMA interrupt, -2 to autoprobe for an 
- * 	IRQ line if overridden on the command line.
  *
- * 3.  When included as a module, with arguments passed on the command line:
- *         ncr_irq=xx	the interrupt
- *         ncr_addr=xx  the port or base address (for port or memory
- *              	mapped, resp.)
- *         ncr_dma=xx	the DMA
- *         ncr_5380=1	to set up for a NCR5380 board
- *         ncr_53c400=1	to set up for a NCR53C400 board
- *     e.g.
- *     modprobe g_NCR5380 ncr_irq=5 ncr_addr=0x350 ncr_5380=1
- *       for a port mapped NCR5380 board or
- *     modprobe g_NCR5380 ncr_irq=255 ncr_addr=0xc8000 ncr_53c400=1
- *       for a memory mapped NCR53C400 board with interrupts disabled.
- * 
- * 255 should be specified for no or DMA interrupt, 254 to autoprobe for an 
- * 	IRQ line if overridden on the command line.
- *     
+ * See Documentation/scsi/g_NCR5380.txt for more info.
  */
 
 #include <asm/io.h>



^ permalink raw reply	[flat|nested] 60+ messages in thread

* [PATCH v4 20/23] atari_scsi: Set a reasonable default for cmd_per_lun
  2016-03-23 10:10 ` Finn Thain
@ 2016-03-23 10:10   ` Finn Thain
  -1 siblings, 0 replies; 60+ messages in thread
From: Finn Thain @ 2016-03-23 10:10 UTC (permalink / raw)
  To: James E.J. Bottomley, Martin K. Petersen, Michael Schmitz,
	linux-m68k, linux-scsi, linux-kernel
  Cc: Ondrej Zary, Sam Creasey

[-- Attachment #1: atari_scsi-cmd_per_lun --]
[-- Type: text/plain, Size: 1586 bytes --]

This setting does not need to be conditional on Atari ST or TT.

Signed-off-by: Finn Thain <fthain@telegraphics.com.au>
Tested-by: Michael Schmitz <schmitzmic@gmail.com>
Reviewed-by: Hannes Reinecke <hare@suse.com>

---

Changed since v1:
- Set the default cmd_per_lun to 4 based on test results.

Changed since v2:
- Revert the default cmd_per_lun to 2, like in the v1 patch, because
a uniform default across all ten 5380 wrapper drivers is worth more
than a tiny improvement in one particular microbenchmark on one system.
Michael tells me that 2 is also the best setting for his Atari Falcon.

---
 drivers/scsi/atari_scsi.c |    3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

Index: linux/drivers/scsi/atari_scsi.c
===================================================================
--- linux.orig/drivers/scsi/atari_scsi.c	2016-03-23 21:09:53.000000000 +1100
+++ linux/drivers/scsi/atari_scsi.c	2016-03-23 21:10:03.000000000 +1100
@@ -752,6 +752,7 @@ static struct scsi_host_template atari_s
 	.eh_abort_handler	= atari_scsi_abort,
 	.eh_bus_reset_handler	= atari_scsi_bus_reset,
 	.this_id		= 7,
+	.cmd_per_lun		= 2,
 	.use_clustering		= DISABLE_CLUSTERING,
 	.cmd_size		= NCR5380_CMD_SIZE,
 };
@@ -788,11 +789,9 @@ static int __init atari_scsi_probe(struc
 	 */
 	if (ATARIHW_PRESENT(TT_SCSI)) {
 		atari_scsi_template.can_queue    = 16;
-		atari_scsi_template.cmd_per_lun  = 8;
 		atari_scsi_template.sg_tablesize = SG_ALL;
 	} else {
 		atari_scsi_template.can_queue    = 8;
-		atari_scsi_template.cmd_per_lun  = 1;
 		atari_scsi_template.sg_tablesize = SG_NONE;
 	}
 

^ permalink raw reply	[flat|nested] 60+ messages in thread

* [PATCH v4 20/23] atari_scsi: Set a reasonable default for cmd_per_lun
@ 2016-03-23 10:10   ` Finn Thain
  0 siblings, 0 replies; 60+ messages in thread
From: Finn Thain @ 2016-03-23 10:10 UTC (permalink / raw)
  To: James E.J. Bottomley, Martin K. Petersen, Michael Schmitz,
	linux-m68k, linux-scsi, linux-kernel
  Cc: Ondrej Zary, Sam Creasey

[-- Attachment #1: atari_scsi-cmd_per_lun --]
[-- Type: text/plain, Size: 1586 bytes --]

This setting does not need to be conditional on Atari ST or TT.

Signed-off-by: Finn Thain <fthain@telegraphics.com.au>
Tested-by: Michael Schmitz <schmitzmic@gmail.com>
Reviewed-by: Hannes Reinecke <hare@suse.com>

---

Changed since v1:
- Set the default cmd_per_lun to 4 based on test results.

Changed since v2:
- Revert the default cmd_per_lun to 2, like in the v1 patch, because
a uniform default across all ten 5380 wrapper drivers is worth more
than a tiny improvement in one particular microbenchmark on one system.
Michael tells me that 2 is also the best setting for his Atari Falcon.

---
 drivers/scsi/atari_scsi.c |    3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

Index: linux/drivers/scsi/atari_scsi.c
===================================================================
--- linux.orig/drivers/scsi/atari_scsi.c	2016-03-23 21:09:53.000000000 +1100
+++ linux/drivers/scsi/atari_scsi.c	2016-03-23 21:10:03.000000000 +1100
@@ -752,6 +752,7 @@ static struct scsi_host_template atari_s
 	.eh_abort_handler	= atari_scsi_abort,
 	.eh_bus_reset_handler	= atari_scsi_bus_reset,
 	.this_id		= 7,
+	.cmd_per_lun		= 2,
 	.use_clustering		= DISABLE_CLUSTERING,
 	.cmd_size		= NCR5380_CMD_SIZE,
 };
@@ -788,11 +789,9 @@ static int __init atari_scsi_probe(struc
 	 */
 	if (ATARIHW_PRESENT(TT_SCSI)) {
 		atari_scsi_template.can_queue    = 16;
-		atari_scsi_template.cmd_per_lun  = 8;
 		atari_scsi_template.sg_tablesize = SG_ALL;
 	} else {
 		atari_scsi_template.can_queue    = 8;
-		atari_scsi_template.cmd_per_lun  = 1;
 		atari_scsi_template.sg_tablesize = SG_NONE;
 	}
 

^ permalink raw reply	[flat|nested] 60+ messages in thread

* [PATCH v4 21/23] atari_scsi: Allow can_queue to be increased for Falcon
  2016-03-23 10:10 ` Finn Thain
@ 2016-03-23 10:10   ` Finn Thain
  -1 siblings, 0 replies; 60+ messages in thread
From: Finn Thain @ 2016-03-23 10:10 UTC (permalink / raw)
  To: James E.J. Bottomley, Martin K. Petersen, Michael Schmitz,
	linux-m68k, linux-scsi, linux-kernel
  Cc: Ondrej Zary, Sam Creasey

[-- Attachment #1: atari_scsi-can_queue --]
[-- Type: text/plain, Size: 6525 bytes --]

The benefit of limiting can_queue to 1 is that atari_scsi shares the
ST DMA chip more fairly with other drivers (e.g. falcon-ide).

Unfortunately, this can limit SCSI bus utilization. On systems without
IDE, atari_scsi should issue SCSI commands whenever it can arbitrate for
the bus. Make that possible by making can_queue configurable.

Signed-off-by: Finn Thain <fthain@telegraphics.com.au>
Reviewed-by: Hannes Reinecke <hare@suse.com>
Tested-by: Michael Schmitz <schmitzmic@gmail.com>

---
 drivers/scsi/atari_scsi.c |   83 ++++++++++++----------------------------------
 1 file changed, 22 insertions(+), 61 deletions(-)

Index: linux/drivers/scsi/atari_scsi.c
===================================================================
--- linux.orig/drivers/scsi/atari_scsi.c	2016-03-23 21:10:03.000000000 +1100
+++ linux/drivers/scsi/atari_scsi.c	2016-03-23 21:10:04.000000000 +1100
@@ -14,55 +14,23 @@
  *
  */
 
-
-/**************************************************************************/
-/*                                                                        */
-/* Notes for Falcon SCSI:                                                 */
-/* ----------------------                                                 */
-/*                                                                        */
-/* Since the Falcon SCSI uses the ST-DMA chip, that is shared among       */
-/* several device drivers, locking and unlocking the access to this       */
-/* chip is required. But locking is not possible from an interrupt,       */
-/* since it puts the process to sleep if the lock is not available.       */
-/* This prevents "late" locking of the DMA chip, i.e. locking it just     */
-/* before using it, since in case of disconnection-reconnection           */
-/* commands, the DMA is started from the reselection interrupt.           */
-/*                                                                        */
-/* Two possible schemes for ST-DMA-locking would be:                      */
-/*  1) The lock is taken for each command separately and disconnecting    */
-/*     is forbidden (i.e. can_queue = 1).                                 */
-/*  2) The DMA chip is locked when the first command comes in and         */
-/*     released when the last command is finished and all queues are      */
-/*     empty.                                                             */
-/* The first alternative would result in bad performance, since the       */
-/* interleaving of commands would not be used. The second is unfair to    */
-/* other drivers using the ST-DMA, because the queues will seldom be      */
-/* totally empty if there is a lot of disk traffic.                       */
-/*                                                                        */
-/* For this reasons I decided to employ a more elaborate scheme:          */
-/*  - First, we give up the lock every time we can (for fairness), this    */
-/*    means every time a command finishes and there are no other commands */
-/*    on the disconnected queue.                                          */
-/*  - If there are others waiting to lock the DMA chip, we stop           */
-/*    issuing commands, i.e. moving them onto the issue queue.           */
-/*    Because of that, the disconnected queue will run empty in a         */
-/*    while. Instead we go to sleep on a 'fairness_queue'.                */
-/*  - If the lock is released, all processes waiting on the fairness      */
-/*    queue will be woken. The first of them tries to re-lock the DMA,     */
-/*    the others wait for the first to finish this task. After that,      */
-/*    they can all run on and do their commands...                        */
-/* This sounds complicated (and it is it :-(), but it seems to be a       */
-/* good compromise between fairness and performance: As long as no one     */
-/* else wants to work with the ST-DMA chip, SCSI can go along as          */
-/* usual. If now someone else comes, this behaviour is changed to a       */
-/* "fairness mode": just already initiated commands are finished and      */
-/* then the lock is released. The other one waiting will probably win     */
-/* the race for locking the DMA, since it was waiting for longer. And     */
-/* after it has finished, SCSI can go ahead again. Finally: I hope I      */
-/* have not produced any deadlock possibilities!                          */
-/*                                                                        */
-/**************************************************************************/
-
+/*
+ * Notes for Falcon SCSI DMA
+ *
+ * The 5380 device is one of several that all share the DMA chip. Hence
+ * "locking" and "unlocking" access to this chip is required.
+ *
+ * Two possible schemes for ST DMA acquisition by atari_scsi are:
+ * 1) The lock is taken for each command separately (i.e. can_queue == 1).
+ * 2) The lock is taken when the first command arrives and released
+ * when the last command is finished (i.e. can_queue > 1).
+ *
+ * The first alternative limits SCSI bus utilization, since interleaving
+ * commands is not possible. The second gives better performance but is
+ * unfair to other drivers needing to use the ST DMA chip. In order to
+ * allow the IDE and floppy drivers equal access to the ST DMA chip
+ * the default is can_queue == 1.
+ */
 
 #include <linux/module.h>
 #include <linux/types.h>
@@ -443,6 +411,10 @@ static int falcon_get_lock(struct Scsi_H
 	if (IS_A_TT())
 		return 1;
 
+	if (stdma_is_locked_by(scsi_falcon_intr) &&
+	    instance->hostt->can_queue > 1)
+		return 1;
+
 	if (in_interrupt())
 		return stdma_try_lock(scsi_falcon_intr, instance);
 
@@ -776,22 +748,11 @@ static int __init atari_scsi_probe(struc
 		atari_scsi_reg_write = atari_scsi_falcon_reg_write;
 	}
 
-	/* The values for CMD_PER_LUN and CAN_QUEUE are somehow arbitrary.
-	 * Higher values should work, too; try it!
-	 * (But cmd_per_lun costs memory!)
-	 *
-	 * But there seems to be a bug somewhere that requires CAN_QUEUE to be
-	 * 2*CMD_PER_LUN. At least on a TT, no spurious timeouts seen since
-	 * changed CMD_PER_LUN...
-	 *
-	 * Note: The Falcon currently uses 8/1 setting due to unsolved problems
-	 * with cmd_per_lun != 1
-	 */
 	if (ATARIHW_PRESENT(TT_SCSI)) {
 		atari_scsi_template.can_queue    = 16;
 		atari_scsi_template.sg_tablesize = SG_ALL;
 	} else {
-		atari_scsi_template.can_queue    = 8;
+		atari_scsi_template.can_queue    = 1;
 		atari_scsi_template.sg_tablesize = SG_NONE;
 	}
 

^ permalink raw reply	[flat|nested] 60+ messages in thread

* [PATCH v4 21/23] atari_scsi: Allow can_queue to be increased for Falcon
@ 2016-03-23 10:10   ` Finn Thain
  0 siblings, 0 replies; 60+ messages in thread
From: Finn Thain @ 2016-03-23 10:10 UTC (permalink / raw)
  To: James E.J. Bottomley, Martin K. Petersen, Michael Schmitz,
	linux-m68k, linux-scsi, linux-kernel
  Cc: Ondrej Zary, Sam Creasey

[-- Attachment #1: atari_scsi-can_queue --]
[-- Type: text/plain, Size: 6525 bytes --]

The benefit of limiting can_queue to 1 is that atari_scsi shares the
ST DMA chip more fairly with other drivers (e.g. falcon-ide).

Unfortunately, this can limit SCSI bus utilization. On systems without
IDE, atari_scsi should issue SCSI commands whenever it can arbitrate for
the bus. Make that possible by making can_queue configurable.

Signed-off-by: Finn Thain <fthain@telegraphics.com.au>
Reviewed-by: Hannes Reinecke <hare@suse.com>
Tested-by: Michael Schmitz <schmitzmic@gmail.com>

---
 drivers/scsi/atari_scsi.c |   83 ++++++++++++----------------------------------
 1 file changed, 22 insertions(+), 61 deletions(-)

Index: linux/drivers/scsi/atari_scsi.c
===================================================================
--- linux.orig/drivers/scsi/atari_scsi.c	2016-03-23 21:10:03.000000000 +1100
+++ linux/drivers/scsi/atari_scsi.c	2016-03-23 21:10:04.000000000 +1100
@@ -14,55 +14,23 @@
  *
  */
 
-
-/**************************************************************************/
-/*                                                                        */
-/* Notes for Falcon SCSI:                                                 */
-/* ----------------------                                                 */
-/*                                                                        */
-/* Since the Falcon SCSI uses the ST-DMA chip, that is shared among       */
-/* several device drivers, locking and unlocking the access to this       */
-/* chip is required. But locking is not possible from an interrupt,       */
-/* since it puts the process to sleep if the lock is not available.       */
-/* This prevents "late" locking of the DMA chip, i.e. locking it just     */
-/* before using it, since in case of disconnection-reconnection           */
-/* commands, the DMA is started from the reselection interrupt.           */
-/*                                                                        */
-/* Two possible schemes for ST-DMA-locking would be:                      */
-/*  1) The lock is taken for each command separately and disconnecting    */
-/*     is forbidden (i.e. can_queue = 1).                                 */
-/*  2) The DMA chip is locked when the first command comes in and         */
-/*     released when the last command is finished and all queues are      */
-/*     empty.                                                             */
-/* The first alternative would result in bad performance, since the       */
-/* interleaving of commands would not be used. The second is unfair to    */
-/* other drivers using the ST-DMA, because the queues will seldom be      */
-/* totally empty if there is a lot of disk traffic.                       */
-/*                                                                        */
-/* For this reasons I decided to employ a more elaborate scheme:          */
-/*  - First, we give up the lock every time we can (for fairness), this    */
-/*    means every time a command finishes and there are no other commands */
-/*    on the disconnected queue.                                          */
-/*  - If there are others waiting to lock the DMA chip, we stop           */
-/*    issuing commands, i.e. moving them onto the issue queue.           */
-/*    Because of that, the disconnected queue will run empty in a         */
-/*    while. Instead we go to sleep on a 'fairness_queue'.                */
-/*  - If the lock is released, all processes waiting on the fairness      */
-/*    queue will be woken. The first of them tries to re-lock the DMA,     */
-/*    the others wait for the first to finish this task. After that,      */
-/*    they can all run on and do their commands...                        */
-/* This sounds complicated (and it is it :-(), but it seems to be a       */
-/* good compromise between fairness and performance: As long as no one     */
-/* else wants to work with the ST-DMA chip, SCSI can go along as          */
-/* usual. If now someone else comes, this behaviour is changed to a       */
-/* "fairness mode": just already initiated commands are finished and      */
-/* then the lock is released. The other one waiting will probably win     */
-/* the race for locking the DMA, since it was waiting for longer. And     */
-/* after it has finished, SCSI can go ahead again. Finally: I hope I      */
-/* have not produced any deadlock possibilities!                          */
-/*                                                                        */
-/**************************************************************************/
-
+/*
+ * Notes for Falcon SCSI DMA
+ *
+ * The 5380 device is one of several that all share the DMA chip. Hence
+ * "locking" and "unlocking" access to this chip is required.
+ *
+ * Two possible schemes for ST DMA acquisition by atari_scsi are:
+ * 1) The lock is taken for each command separately (i.e. can_queue == 1).
+ * 2) The lock is taken when the first command arrives and released
+ * when the last command is finished (i.e. can_queue > 1).
+ *
+ * The first alternative limits SCSI bus utilization, since interleaving
+ * commands is not possible. The second gives better performance but is
+ * unfair to other drivers needing to use the ST DMA chip. In order to
+ * allow the IDE and floppy drivers equal access to the ST DMA chip
+ * the default is can_queue == 1.
+ */
 
 #include <linux/module.h>
 #include <linux/types.h>
@@ -443,6 +411,10 @@ static int falcon_get_lock(struct Scsi_H
 	if (IS_A_TT())
 		return 1;
 
+	if (stdma_is_locked_by(scsi_falcon_intr) &&
+	    instance->hostt->can_queue > 1)
+		return 1;
+
 	if (in_interrupt())
 		return stdma_try_lock(scsi_falcon_intr, instance);
 
@@ -776,22 +748,11 @@ static int __init atari_scsi_probe(struc
 		atari_scsi_reg_write = atari_scsi_falcon_reg_write;
 	}
 
-	/* The values for CMD_PER_LUN and CAN_QUEUE are somehow arbitrary.
-	 * Higher values should work, too; try it!
-	 * (But cmd_per_lun costs memory!)
-	 *
-	 * But there seems to be a bug somewhere that requires CAN_QUEUE to be
-	 * 2*CMD_PER_LUN. At least on a TT, no spurious timeouts seen since
-	 * changed CMD_PER_LUN...
-	 *
-	 * Note: The Falcon currently uses 8/1 setting due to unsolved problems
-	 * with cmd_per_lun != 1
-	 */
 	if (ATARIHW_PRESENT(TT_SCSI)) {
 		atari_scsi_template.can_queue    = 16;
 		atari_scsi_template.sg_tablesize = SG_ALL;
 	} else {
-		atari_scsi_template.can_queue    = 8;
+		atari_scsi_template.can_queue    = 1;
 		atari_scsi_template.sg_tablesize = SG_NONE;
 	}
 

^ permalink raw reply	[flat|nested] 60+ messages in thread

* [PATCH v4 22/23] mac_scsi: Fix pseudo DMA implementation
  2016-03-23 10:10 ` Finn Thain
@ 2016-03-23 10:10   ` Finn Thain
  -1 siblings, 0 replies; 60+ messages in thread
From: Finn Thain @ 2016-03-23 10:10 UTC (permalink / raw)
  To: James E.J. Bottomley, Martin K. Petersen, Michael Schmitz,
	linux-m68k, linux-scsi, linux-kernel
  Cc: Ondrej Zary, Sam Creasey

[-- Attachment #1: mac_scsi-pdma-fixes --]
[-- Type: text/plain, Size: 11863 bytes --]

Fix various issues: Comments about bus errors are incorrect. The
PDMA asm must return the size of the memory access that faulted so the
transfer count can be adjusted accordingly. A phase change may cause a
bus error but should not be treated as failure. A bus error does not
always imply a phase change and generally the transfer may continue.
Scatter/gather doesn't seem to work with PDMA due to overruns. This is
a pity because peak throughput seems to double with SG_ALL.
Tested on a Mac LC III and a PowerBook 520.

Signed-off-by: Finn Thain <fthain@telegraphics.com.au>
Reviewed-by: Hannes Reinecke <hare@suse.com>

---

Changed since v1:
- Set the default cmd_per_lun to 4 based on test results.

Changed since v2:
- Revert the default cmd_per_lun to 2, like in the v1 patch, because
a uniform default across all ten 5380 wrapper drivers is worth more
than a tiny improvement in one particular microbenchmark on one system.
- Add 'reviewed-by' tag.

---
 drivers/scsi/NCR5380.h  |    2 
 drivers/scsi/mac_scsi.c |  210 ++++++++++++++++++++++++++----------------------
 2 files changed, 118 insertions(+), 94 deletions(-)

Index: linux/drivers/scsi/mac_scsi.c
===================================================================
--- linux.orig/drivers/scsi/mac_scsi.c	2016-03-23 21:09:53.000000000 +1100
+++ linux/drivers/scsi/mac_scsi.c	2016-03-23 21:10:05.000000000 +1100
@@ -28,7 +28,8 @@
 
 /* Definitions for the core NCR5380 driver. */
 
-#define NCR5380_implementation_fields   unsigned char *pdma_base
+#define NCR5380_implementation_fields   unsigned char *pdma_base; \
+                                        int pdma_residual
 
 #define NCR5380_read(reg)               macscsi_read(instance, reg)
 #define NCR5380_write(reg, value)       macscsi_write(instance, reg, value)
@@ -37,7 +38,7 @@
         macscsi_dma_xfer_len(instance, cmd)
 #define NCR5380_dma_recv_setup          macscsi_pread
 #define NCR5380_dma_send_setup          macscsi_pwrite
-#define NCR5380_dma_residual(instance)  (0)
+#define NCR5380_dma_residual(instance)  (hostdata->pdma_residual)
 
 #define NCR5380_intr                    macscsi_intr
 #define NCR5380_queue_command           macscsi_queue_command
@@ -104,18 +105,9 @@ static int __init mac_scsi_setup(char *s
 __setup("mac5380=", mac_scsi_setup);
 #endif /* !MODULE */
 
-/* 
-   Pseudo-DMA: (Ove Edlund)
-   The code attempts to catch bus errors that occur if one for example
-   "trips over the cable".
-   XXX: Since bus errors in the PDMA routines never happen on my 
-   computer, the bus error code is untested. 
-   If the code works as intended, a bus error results in Pseudo-DMA 
-   being disabled, meaning that the driver switches to slow handshake.
-   If bus errors are NOT extremely rare, this has to be changed. 
-*/
+/* Pseudo DMA asm originally by Ove Edlund */
 
-#define CP_IO_TO_MEM(s,d,len)				\
+#define CP_IO_TO_MEM(s,d,n)				\
 __asm__ __volatile__					\
     ("    cmp.w  #4,%2\n"				\
      "    bls    8f\n"					\
@@ -152,61 +144,73 @@ __asm__ __volatile__					\
      " 9: \n"						\
      ".section .fixup,\"ax\"\n"				\
      "    .even\n"					\
-     "90: moveq.l #1, %2\n"				\
+     "91: moveq.l #1, %2\n"				\
+     "    jra 9b\n"					\
+     "94: moveq.l #4, %2\n"				\
      "    jra 9b\n"					\
      ".previous\n"					\
      ".section __ex_table,\"a\"\n"			\
      "   .align 4\n"					\
-     "   .long  1b,90b\n"				\
-     "   .long  3b,90b\n"				\
-     "   .long 31b,90b\n"				\
-     "   .long 32b,90b\n"				\
-     "   .long 33b,90b\n"				\
-     "   .long 34b,90b\n"				\
-     "   .long 35b,90b\n"				\
-     "   .long 36b,90b\n"				\
-     "   .long 37b,90b\n"				\
-     "   .long  5b,90b\n"				\
-     "   .long  7b,90b\n"				\
+     "   .long  1b,91b\n"				\
+     "   .long  3b,94b\n"				\
+     "   .long 31b,94b\n"				\
+     "   .long 32b,94b\n"				\
+     "   .long 33b,94b\n"				\
+     "   .long 34b,94b\n"				\
+     "   .long 35b,94b\n"				\
+     "   .long 36b,94b\n"				\
+     "   .long 37b,94b\n"				\
+     "   .long  5b,94b\n"				\
+     "   .long  7b,91b\n"				\
      ".previous"					\
-     : "=a"(s), "=a"(d), "=d"(len)			\
-     : "0"(s), "1"(d), "2"(len)				\
+     : "=a"(s), "=a"(d), "=d"(n)			\
+     : "0"(s), "1"(d), "2"(n)				\
      : "d0")
 
 static int macscsi_pread(struct Scsi_Host *instance,
                          unsigned char *dst, int len)
 {
 	struct NCR5380_hostdata *hostdata = shost_priv(instance);
-	unsigned char *d;
-	unsigned char *s;
-
-	s = hostdata->pdma_base + (INPUT_DATA_REG << 4);
-	d = dst;
-
-	/* These conditions are derived from MacOS */
-
-	while (!(NCR5380_read(BUS_AND_STATUS_REG) & BASR_DRQ) &&
-	       !(NCR5380_read(STATUS_REG) & SR_REQ))
-		;
-
-	if (!(NCR5380_read(BUS_AND_STATUS_REG) & BASR_DRQ) &&
-	    (NCR5380_read(BUS_AND_STATUS_REG) & BASR_PHASE_MATCH)) {
-		pr_err("Error in macscsi_pread\n");
-		return -1;
-	}
-
-	CP_IO_TO_MEM(s, d, len);
-
-	if (len != 0) {
-		pr_notice("Bus error in macscsi_pread\n");
-		return -1;
+	unsigned char *s = hostdata->pdma_base + (INPUT_DATA_REG << 4);
+	unsigned char *d = dst;
+	int n = len;
+	int transferred;
+
+	while (!NCR5380_poll_politely(instance, BUS_AND_STATUS_REG,
+	                              BASR_DRQ | BASR_PHASE_MATCH,
+	                              BASR_DRQ | BASR_PHASE_MATCH, HZ / 64)) {
+		CP_IO_TO_MEM(s, d, n);
+
+		transferred = d - dst - n;
+		hostdata->pdma_residual = len - transferred;
+
+		/* No bus error. */
+		if (n == 0)
+			return 0;
+
+		/* Target changed phase early? */
+		if (NCR5380_poll_politely2(instance, STATUS_REG, SR_REQ, SR_REQ,
+		                           BUS_AND_STATUS_REG, BASR_ACK, BASR_ACK, HZ / 64) < 0)
+			scmd_printk(KERN_ERR, hostdata->connected,
+			            "%s: !REQ and !ACK\n", __func__);
+		if (!(NCR5380_read(BUS_AND_STATUS_REG) & BASR_PHASE_MATCH))
+			return 0;
+
+		dsprintk(NDEBUG_PSEUDO_DMA, instance,
+		         "%s: bus error (%d/%d)\n", __func__, transferred, len);
+		NCR5380_dprint(NDEBUG_PSEUDO_DMA, instance);
+		d = dst + transferred;
+		n = len - transferred;
 	}
 
-	return 0;
+	scmd_printk(KERN_ERR, hostdata->connected,
+	            "%s: phase mismatch or !DRQ\n", __func__);
+	NCR5380_dprint(NDEBUG_PSEUDO_DMA, instance);
+	return -1;
 }
 
 
-#define CP_MEM_TO_IO(s,d,len)				\
+#define CP_MEM_TO_IO(s,d,n)				\
 __asm__ __volatile__					\
     ("    cmp.w  #4,%2\n"				\
      "    bls    8f\n"					\
@@ -243,57 +247,76 @@ __asm__ __volatile__					\
      " 9: \n"						\
      ".section .fixup,\"ax\"\n"				\
      "    .even\n"					\
-     "90: moveq.l #1, %2\n"				\
+     "91: moveq.l #1, %2\n"				\
+     "    jra 9b\n"					\
+     "94: moveq.l #4, %2\n"				\
      "    jra 9b\n"					\
      ".previous\n"					\
      ".section __ex_table,\"a\"\n"			\
      "   .align 4\n"					\
-     "   .long  1b,90b\n"				\
-     "   .long  3b,90b\n"				\
-     "   .long 31b,90b\n"				\
-     "   .long 32b,90b\n"				\
-     "   .long 33b,90b\n"				\
-     "   .long 34b,90b\n"				\
-     "   .long 35b,90b\n"				\
-     "   .long 36b,90b\n"				\
-     "   .long 37b,90b\n"				\
-     "   .long  5b,90b\n"				\
-     "   .long  7b,90b\n"				\
+     "   .long  1b,91b\n"				\
+     "   .long  3b,94b\n"				\
+     "   .long 31b,94b\n"				\
+     "   .long 32b,94b\n"				\
+     "   .long 33b,94b\n"				\
+     "   .long 34b,94b\n"				\
+     "   .long 35b,94b\n"				\
+     "   .long 36b,94b\n"				\
+     "   .long 37b,94b\n"				\
+     "   .long  5b,94b\n"				\
+     "   .long  7b,91b\n"				\
      ".previous"					\
-     : "=a"(s), "=a"(d), "=d"(len)			\
-     : "0"(s), "1"(d), "2"(len)				\
+     : "=a"(s), "=a"(d), "=d"(n)			\
+     : "0"(s), "1"(d), "2"(n)				\
      : "d0")
 
 static int macscsi_pwrite(struct Scsi_Host *instance,
                           unsigned char *src, int len)
 {
 	struct NCR5380_hostdata *hostdata = shost_priv(instance);
-	unsigned char *s;
-	unsigned char *d;
-
-	s = src;
-	d = hostdata->pdma_base + (OUTPUT_DATA_REG << 4);
-
-	/* These conditions are derived from MacOS */
-
-	while (!(NCR5380_read(BUS_AND_STATUS_REG) & BASR_DRQ) &&
-	       (!(NCR5380_read(STATUS_REG) & SR_REQ) ||
-	        (NCR5380_read(BUS_AND_STATUS_REG) & BASR_PHASE_MATCH)))
-		;
-
-	if (!(NCR5380_read(BUS_AND_STATUS_REG) & BASR_DRQ)) {
-		pr_err("Error in macscsi_pwrite\n");
-		return -1;
+	unsigned char *s = src;
+	unsigned char *d = hostdata->pdma_base + (OUTPUT_DATA_REG << 4);
+	int n = len;
+	int transferred;
+
+	while (!NCR5380_poll_politely(instance, BUS_AND_STATUS_REG,
+	                              BASR_DRQ | BASR_PHASE_MATCH,
+	                              BASR_DRQ | BASR_PHASE_MATCH, HZ / 64)) {
+		CP_MEM_TO_IO(s, d, n);
+
+		transferred = s - src - n;
+		hostdata->pdma_residual = len - transferred;
+
+		/* Target changed phase early? */
+		if (NCR5380_poll_politely2(instance, STATUS_REG, SR_REQ, SR_REQ,
+		                           BUS_AND_STATUS_REG, BASR_ACK, BASR_ACK, HZ / 64) < 0)
+			scmd_printk(KERN_ERR, hostdata->connected,
+			            "%s: !REQ and !ACK\n", __func__);
+		if (!(NCR5380_read(BUS_AND_STATUS_REG) & BASR_PHASE_MATCH))
+			return 0;
+
+		/* No bus error. */
+		if (n == 0) {
+			if (NCR5380_poll_politely(instance, TARGET_COMMAND_REG,
+			                          TCR_LAST_BYTE_SENT,
+			                          TCR_LAST_BYTE_SENT, HZ / 64) < 0)
+				scmd_printk(KERN_ERR, hostdata->connected,
+				            "%s: Last Byte Sent timeout\n", __func__);
+			return 0;
+		}
+
+		dsprintk(NDEBUG_PSEUDO_DMA, instance,
+		         "%s: bus error (%d/%d)\n", __func__, transferred, len);
+		NCR5380_dprint(NDEBUG_PSEUDO_DMA, instance);
+		s = src + transferred;
+		n = len - transferred;
 	}
 
-	CP_MEM_TO_IO(s, d, len);
-
-	if (len != 0) {
-		pr_notice("Bus error in macscsi_pwrite\n");
-		return -1;
-	}
+	scmd_printk(KERN_ERR, hostdata->connected,
+	            "%s: phase mismatch or !DRQ\n", __func__);
+	NCR5380_dprint(NDEBUG_PSEUDO_DMA, instance);
 
-	return 0;
+	return -1;
 }
 
 static int macscsi_dma_xfer_len(struct Scsi_Host *instance,
@@ -301,10 +324,11 @@ static int macscsi_dma_xfer_len(struct S
 {
 	struct NCR5380_hostdata *hostdata = shost_priv(instance);
 
-	if (hostdata->flags & FLAG_NO_PSEUDO_DMA)
+	if (hostdata->flags & FLAG_NO_PSEUDO_DMA ||
+	    cmd->SCp.this_residual < 16)
 		return 0;
 
-	return cmd->transfersize;
+	return cmd->SCp.this_residual;
 }
 
 #include "NCR5380.c"
@@ -322,7 +346,7 @@ static struct scsi_host_template mac_scs
 	.eh_bus_reset_handler	= macscsi_bus_reset,
 	.can_queue		= 16,
 	.this_id		= 7,
-	.sg_tablesize		= SG_ALL,
+	.sg_tablesize		= 1,
 	.cmd_per_lun		= 2,
 	.use_clustering		= DISABLE_CLUSTERING,
 	.cmd_size		= NCR5380_CMD_SIZE,
@@ -358,8 +382,6 @@ static int __init mac_scsi_probe(struct
 		mac_scsi_template.sg_tablesize = setup_sg_tablesize;
 	if (setup_hostid >= 0)
 		mac_scsi_template.this_id = setup_hostid & 7;
-	if (setup_use_pdma < 0)
-		setup_use_pdma = 0;
 
 	instance = scsi_host_alloc(&mac_scsi_template,
 	                           sizeof(struct NCR5380_hostdata));
Index: linux/drivers/scsi/NCR5380.h
===================================================================
--- linux.orig/drivers/scsi/NCR5380.h	2016-03-23 21:10:00.000000000 +1100
+++ linux/drivers/scsi/NCR5380.h	2016-03-23 21:10:05.000000000 +1100
@@ -292,6 +292,8 @@ static void NCR5380_reselect(struct Scsi
 static struct scsi_cmnd *NCR5380_select(struct Scsi_Host *, struct scsi_cmnd *);
 static int NCR5380_transfer_dma(struct Scsi_Host *instance, unsigned char *phase, int *count, unsigned char **data);
 static int NCR5380_transfer_pio(struct Scsi_Host *instance, unsigned char *phase, int *count, unsigned char **data);
+static int NCR5380_poll_politely(struct Scsi_Host *, int, int, int, int);
+static int NCR5380_poll_politely2(struct Scsi_Host *, int, int, int, int, int, int, int);
 
 #endif				/* __KERNEL__ */
 #endif				/* NCR5380_H */

^ permalink raw reply	[flat|nested] 60+ messages in thread

* [PATCH v4 22/23] mac_scsi: Fix pseudo DMA implementation
@ 2016-03-23 10:10   ` Finn Thain
  0 siblings, 0 replies; 60+ messages in thread
From: Finn Thain @ 2016-03-23 10:10 UTC (permalink / raw)
  To: James E.J. Bottomley, Martin K. Petersen, Michael Schmitz,
	linux-m68k, linux-scsi, linux-kernel
  Cc: Ondrej Zary, Sam Creasey

[-- Attachment #1: mac_scsi-pdma-fixes --]
[-- Type: text/plain, Size: 11865 bytes --]

Fix various issues: Comments about bus errors are incorrect. The
PDMA asm must return the size of the memory access that faulted so the
transfer count can be adjusted accordingly. A phase change may cause a
bus error but should not be treated as failure. A bus error does not
always imply a phase change and generally the transfer may continue.
Scatter/gather doesn't seem to work with PDMA due to overruns. This is
a pity because peak throughput seems to double with SG_ALL.
Tested on a Mac LC III and a PowerBook 520.

Signed-off-by: Finn Thain <fthain@telegraphics.com.au>
Reviewed-by: Hannes Reinecke <hare@suse.com>

---

Changed since v1:
- Set the default cmd_per_lun to 4 based on test results.

Changed since v2:
- Revert the default cmd_per_lun to 2, like in the v1 patch, because
a uniform default across all ten 5380 wrapper drivers is worth more
than a tiny improvement in one particular microbenchmark on one system.
- Add 'reviewed-by' tag.

---
 drivers/scsi/NCR5380.h  |    2 
 drivers/scsi/mac_scsi.c |  210 ++++++++++++++++++++++++++----------------------
 2 files changed, 118 insertions(+), 94 deletions(-)

Index: linux/drivers/scsi/mac_scsi.c
===================================================================
--- linux.orig/drivers/scsi/mac_scsi.c	2016-03-23 21:09:53.000000000 +1100
+++ linux/drivers/scsi/mac_scsi.c	2016-03-23 21:10:05.000000000 +1100
@@ -28,7 +28,8 @@
 
 /* Definitions for the core NCR5380 driver. */
 
-#define NCR5380_implementation_fields   unsigned char *pdma_base
+#define NCR5380_implementation_fields   unsigned char *pdma_base; \
+                                        int pdma_residual
 
 #define NCR5380_read(reg)               macscsi_read(instance, reg)
 #define NCR5380_write(reg, value)       macscsi_write(instance, reg, value)
@@ -37,7 +38,7 @@
         macscsi_dma_xfer_len(instance, cmd)
 #define NCR5380_dma_recv_setup          macscsi_pread
 #define NCR5380_dma_send_setup          macscsi_pwrite
-#define NCR5380_dma_residual(instance)  (0)
+#define NCR5380_dma_residual(instance)  (hostdata->pdma_residual)
 
 #define NCR5380_intr                    macscsi_intr
 #define NCR5380_queue_command           macscsi_queue_command
@@ -104,18 +105,9 @@ static int __init mac_scsi_setup(char *s
 __setup("mac5380=", mac_scsi_setup);
 #endif /* !MODULE */
 
-/* 
-   Pseudo-DMA: (Ove Edlund)
-   The code attempts to catch bus errors that occur if one for example
-   "trips over the cable".
-   XXX: Since bus errors in the PDMA routines never happen on my 
-   computer, the bus error code is untested. 
-   If the code works as intended, a bus error results in Pseudo-DMA 
-   being disabled, meaning that the driver switches to slow handshake.
-   If bus errors are NOT extremely rare, this has to be changed. 
-*/
+/* Pseudo DMA asm originally by Ove Edlund */
 
-#define CP_IO_TO_MEM(s,d,len)				\
+#define CP_IO_TO_MEM(s,d,n)				\
 __asm__ __volatile__					\
     ("    cmp.w  #4,%2\n"				\
      "    bls    8f\n"					\
@@ -152,61 +144,73 @@ __asm__ __volatile__					\
      " 9: \n"						\
      ".section .fixup,\"ax\"\n"				\
      "    .even\n"					\
-     "90: moveq.l #1, %2\n"				\
+     "91: moveq.l #1, %2\n"				\
+     "    jra 9b\n"					\
+     "94: moveq.l #4, %2\n"				\
      "    jra 9b\n"					\
      ".previous\n"					\
      ".section __ex_table,\"a\"\n"			\
      "   .align 4\n"					\
-     "   .long  1b,90b\n"				\
-     "   .long  3b,90b\n"				\
-     "   .long 31b,90b\n"				\
-     "   .long 32b,90b\n"				\
-     "   .long 33b,90b\n"				\
-     "   .long 34b,90b\n"				\
-     "   .long 35b,90b\n"				\
-     "   .long 36b,90b\n"				\
-     "   .long 37b,90b\n"				\
-     "   .long  5b,90b\n"				\
-     "   .long  7b,90b\n"				\
+     "   .long  1b,91b\n"				\
+     "   .long  3b,94b\n"				\
+     "   .long 31b,94b\n"				\
+     "   .long 32b,94b\n"				\
+     "   .long 33b,94b\n"				\
+     "   .long 34b,94b\n"				\
+     "   .long 35b,94b\n"				\
+     "   .long 36b,94b\n"				\
+     "   .long 37b,94b\n"				\
+     "   .long  5b,94b\n"				\
+     "   .long  7b,91b\n"				\
      ".previous"					\
-     : "=a"(s), "=a"(d), "=d"(len)			\
-     : "0"(s), "1"(d), "2"(len)				\
+     : "=a"(s), "=a"(d), "=d"(n)			\
+     : "0"(s), "1"(d), "2"(n)				\
      : "d0")
 
 static int macscsi_pread(struct Scsi_Host *instance,
                          unsigned char *dst, int len)
 {
 	struct NCR5380_hostdata *hostdata = shost_priv(instance);
-	unsigned char *d;
-	unsigned char *s;
-
-	s = hostdata->pdma_base + (INPUT_DATA_REG << 4);
-	d = dst;
-
-	/* These conditions are derived from MacOS */
-
-	while (!(NCR5380_read(BUS_AND_STATUS_REG) & BASR_DRQ) &&
-	       !(NCR5380_read(STATUS_REG) & SR_REQ))
-		;
-
-	if (!(NCR5380_read(BUS_AND_STATUS_REG) & BASR_DRQ) &&
-	    (NCR5380_read(BUS_AND_STATUS_REG) & BASR_PHASE_MATCH)) {
-		pr_err("Error in macscsi_pread\n");
-		return -1;
-	}
-
-	CP_IO_TO_MEM(s, d, len);
-
-	if (len != 0) {
-		pr_notice("Bus error in macscsi_pread\n");
-		return -1;
+	unsigned char *s = hostdata->pdma_base + (INPUT_DATA_REG << 4);
+	unsigned char *d = dst;
+	int n = len;
+	int transferred;
+
+	while (!NCR5380_poll_politely(instance, BUS_AND_STATUS_REG,
+	                              BASR_DRQ | BASR_PHASE_MATCH,
+	                              BASR_DRQ | BASR_PHASE_MATCH, HZ / 64)) {
+		CP_IO_TO_MEM(s, d, n);
+
+		transferred = d - dst - n;
+		hostdata->pdma_residual = len - transferred;
+
+		/* No bus error. */
+		if (n == 0)
+			return 0;
+
+		/* Target changed phase early? */
+		if (NCR5380_poll_politely2(instance, STATUS_REG, SR_REQ, SR_REQ,
+		                           BUS_AND_STATUS_REG, BASR_ACK, BASR_ACK, HZ / 64) < 0)
+			scmd_printk(KERN_ERR, hostdata->connected,
+			            "%s: !REQ and !ACK\n", __func__);
+		if (!(NCR5380_read(BUS_AND_STATUS_REG) & BASR_PHASE_MATCH))
+			return 0;
+
+		dsprintk(NDEBUG_PSEUDO_DMA, instance,
+		         "%s: bus error (%d/%d)\n", __func__, transferred, len);
+		NCR5380_dprint(NDEBUG_PSEUDO_DMA, instance);
+		d = dst + transferred;
+		n = len - transferred;
 	}
 
-	return 0;
+	scmd_printk(KERN_ERR, hostdata->connected,
+	            "%s: phase mismatch or !DRQ\n", __func__);
+	NCR5380_dprint(NDEBUG_PSEUDO_DMA, instance);
+	return -1;
 }
 
 
-#define CP_MEM_TO_IO(s,d,len)				\
+#define CP_MEM_TO_IO(s,d,n)				\
 __asm__ __volatile__					\
     ("    cmp.w  #4,%2\n"				\
      "    bls    8f\n"					\
@@ -243,57 +247,76 @@ __asm__ __volatile__					\
      " 9: \n"						\
      ".section .fixup,\"ax\"\n"				\
      "    .even\n"					\
-     "90: moveq.l #1, %2\n"				\
+     "91: moveq.l #1, %2\n"				\
+     "    jra 9b\n"					\
+     "94: moveq.l #4, %2\n"				\
      "    jra 9b\n"					\
      ".previous\n"					\
      ".section __ex_table,\"a\"\n"			\
      "   .align 4\n"					\
-     "   .long  1b,90b\n"				\
-     "   .long  3b,90b\n"				\
-     "   .long 31b,90b\n"				\
-     "   .long 32b,90b\n"				\
-     "   .long 33b,90b\n"				\
-     "   .long 34b,90b\n"				\
-     "   .long 35b,90b\n"				\
-     "   .long 36b,90b\n"				\
-     "   .long 37b,90b\n"				\
-     "   .long  5b,90b\n"				\
-     "   .long  7b,90b\n"				\
+     "   .long  1b,91b\n"				\
+     "   .long  3b,94b\n"				\
+     "   .long 31b,94b\n"				\
+     "   .long 32b,94b\n"				\
+     "   .long 33b,94b\n"				\
+     "   .long 34b,94b\n"				\
+     "   .long 35b,94b\n"				\
+     "   .long 36b,94b\n"				\
+     "   .long 37b,94b\n"				\
+     "   .long  5b,94b\n"				\
+     "   .long  7b,91b\n"				\
      ".previous"					\
-     : "=a"(s), "=a"(d), "=d"(len)			\
-     : "0"(s), "1"(d), "2"(len)				\
+     : "=a"(s), "=a"(d), "=d"(n)			\
+     : "0"(s), "1"(d), "2"(n)				\
      : "d0")
 
 static int macscsi_pwrite(struct Scsi_Host *instance,
                           unsigned char *src, int len)
 {
 	struct NCR5380_hostdata *hostdata = shost_priv(instance);
-	unsigned char *s;
-	unsigned char *d;
-
-	s = src;
-	d = hostdata->pdma_base + (OUTPUT_DATA_REG << 4);
-
-	/* These conditions are derived from MacOS */
-
-	while (!(NCR5380_read(BUS_AND_STATUS_REG) & BASR_DRQ) &&
-	       (!(NCR5380_read(STATUS_REG) & SR_REQ) ||
-	        (NCR5380_read(BUS_AND_STATUS_REG) & BASR_PHASE_MATCH)))
-		;
-
-	if (!(NCR5380_read(BUS_AND_STATUS_REG) & BASR_DRQ)) {
-		pr_err("Error in macscsi_pwrite\n");
-		return -1;
+	unsigned char *s = src;
+	unsigned char *d = hostdata->pdma_base + (OUTPUT_DATA_REG << 4);
+	int n = len;
+	int transferred;
+
+	while (!NCR5380_poll_politely(instance, BUS_AND_STATUS_REG,
+	                              BASR_DRQ | BASR_PHASE_MATCH,
+	                              BASR_DRQ | BASR_PHASE_MATCH, HZ / 64)) {
+		CP_MEM_TO_IO(s, d, n);
+
+		transferred = s - src - n;
+		hostdata->pdma_residual = len - transferred;
+
+		/* Target changed phase early? */
+		if (NCR5380_poll_politely2(instance, STATUS_REG, SR_REQ, SR_REQ,
+		                           BUS_AND_STATUS_REG, BASR_ACK, BASR_ACK, HZ / 64) < 0)
+			scmd_printk(KERN_ERR, hostdata->connected,
+			            "%s: !REQ and !ACK\n", __func__);
+		if (!(NCR5380_read(BUS_AND_STATUS_REG) & BASR_PHASE_MATCH))
+			return 0;
+
+		/* No bus error. */
+		if (n == 0) {
+			if (NCR5380_poll_politely(instance, TARGET_COMMAND_REG,
+			                          TCR_LAST_BYTE_SENT,
+			                          TCR_LAST_BYTE_SENT, HZ / 64) < 0)
+				scmd_printk(KERN_ERR, hostdata->connected,
+				            "%s: Last Byte Sent timeout\n", __func__);
+			return 0;
+		}
+
+		dsprintk(NDEBUG_PSEUDO_DMA, instance,
+		         "%s: bus error (%d/%d)\n", __func__, transferred, len);
+		NCR5380_dprint(NDEBUG_PSEUDO_DMA, instance);
+		s = src + transferred;
+		n = len - transferred;
 	}
 
-	CP_MEM_TO_IO(s, d, len);
-
-	if (len != 0) {
-		pr_notice("Bus error in macscsi_pwrite\n");
-		return -1;
-	}
+	scmd_printk(KERN_ERR, hostdata->connected,
+	            "%s: phase mismatch or !DRQ\n", __func__);
+	NCR5380_dprint(NDEBUG_PSEUDO_DMA, instance);
 
-	return 0;
+	return -1;
 }
 
 static int macscsi_dma_xfer_len(struct Scsi_Host *instance,
@@ -301,10 +324,11 @@ static int macscsi_dma_xfer_len(struct S
 {
 	struct NCR5380_hostdata *hostdata = shost_priv(instance);
 
-	if (hostdata->flags & FLAG_NO_PSEUDO_DMA)
+	if (hostdata->flags & FLAG_NO_PSEUDO_DMA ||
+	    cmd->SCp.this_residual < 16)
 		return 0;
 
-	return cmd->transfersize;
+	return cmd->SCp.this_residual;
 }
 
 #include "NCR5380.c"
@@ -322,7 +346,7 @@ static struct scsi_host_template mac_scs
 	.eh_bus_reset_handler	= macscsi_bus_reset,
 	.can_queue		= 16,
 	.this_id		= 7,
-	.sg_tablesize		= SG_ALL,
+	.sg_tablesize		= 1,
 	.cmd_per_lun		= 2,
 	.use_clustering		= DISABLE_CLUSTERING,
 	.cmd_size		= NCR5380_CMD_SIZE,
@@ -358,8 +382,6 @@ static int __init mac_scsi_probe(struct
 		mac_scsi_template.sg_tablesize = setup_sg_tablesize;
 	if (setup_hostid >= 0)
 		mac_scsi_template.this_id = setup_hostid & 7;
-	if (setup_use_pdma < 0)
-		setup_use_pdma = 0;
 
 	instance = scsi_host_alloc(&mac_scsi_template,
 	                           sizeof(struct NCR5380_hostdata));
Index: linux/drivers/scsi/NCR5380.h
===================================================================
--- linux.orig/drivers/scsi/NCR5380.h	2016-03-23 21:10:00.000000000 +1100
+++ linux/drivers/scsi/NCR5380.h	2016-03-23 21:10:05.000000000 +1100
@@ -292,6 +292,8 @@ static void NCR5380_reselect(struct Scsi
 static struct scsi_cmnd *NCR5380_select(struct Scsi_Host *, struct scsi_cmnd *);
 static int NCR5380_transfer_dma(struct Scsi_Host *instance, unsigned char *phase, int *count, unsigned char **data);
 static int NCR5380_transfer_pio(struct Scsi_Host *instance, unsigned char *phase, int *count, unsigned char **data);
+static int NCR5380_poll_politely(struct Scsi_Host *, int, int, int, int);
+static int NCR5380_poll_politely2(struct Scsi_Host *, int, int, int, int, int, int, int);
 
 #endif				/* __KERNEL__ */
 #endif				/* NCR5380_H */



^ permalink raw reply	[flat|nested] 60+ messages in thread

* [PATCH v4 23/23] ncr5380: Call complete_cmd() for disconnected commands on bus reset
  2016-03-23 10:10 ` Finn Thain
@ 2016-03-23 10:10   ` Finn Thain
  -1 siblings, 0 replies; 60+ messages in thread
From: Finn Thain @ 2016-03-23 10:10 UTC (permalink / raw)
  To: James E.J. Bottomley, Martin K. Petersen, Michael Schmitz,
	linux-m68k, linux-scsi, linux-kernel
  Cc: Ondrej Zary, Sam Creasey

[-- Attachment #1: ncr5380-disconnected-autosense-fix --]
[-- Type: text/plain, Size: 1226 bytes --]

I'm told that some targets are liable to disconnect a REQUEST SENSE
command. Theoretically this would cause a command undergoing autosense to
be moved onto the disconnected list. The bus reset handler must call
complete_cmd() for these commands, otherwise the hostdata->sensing pointer
will not get cleared. That would cause autosense processing to stall and
a timeout or an incorrect scsi_eh_restore_cmnd() would eventually follow.

Signed-off-by: Finn Thain <fthain@telegraphics.com.au>
Reported-by: Michael Schmitz <schmitzmic@gmail.com>
Tested-by: Ondrej Zary <linux@rainbow-software.org>
Reviewed-by: Hannes Reinecke <hare@suse.com>

---
 drivers/scsi/NCR5380.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

Index: linux/drivers/scsi/NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/NCR5380.c	2016-03-23 21:10:00.000000000 +1100
+++ linux/drivers/scsi/NCR5380.c	2016-03-23 21:10:07.000000000 +1100
@@ -2437,7 +2437,7 @@ static int NCR5380_bus_reset(struct scsi
 		struct scsi_cmnd *cmd = NCR5380_to_scmd(ncmd);
 
 		set_host_byte(cmd, DID_RESET);
-		cmd->scsi_done(cmd);
+		complete_cmd(instance, cmd);
 	}
 	INIT_LIST_HEAD(&hostdata->disconnected);
 

^ permalink raw reply	[flat|nested] 60+ messages in thread

* [PATCH v4 23/23] ncr5380: Call complete_cmd() for disconnected commands on bus reset
@ 2016-03-23 10:10   ` Finn Thain
  0 siblings, 0 replies; 60+ messages in thread
From: Finn Thain @ 2016-03-23 10:10 UTC (permalink / raw)
  To: James E.J. Bottomley, Martin K. Petersen, Michael Schmitz,
	linux-m68k, linux-scsi, linux-kernel
  Cc: Ondrej Zary, Sam Creasey

[-- Attachment #1: ncr5380-disconnected-autosense-fix --]
[-- Type: text/plain, Size: 1228 bytes --]

I'm told that some targets are liable to disconnect a REQUEST SENSE
command. Theoretically this would cause a command undergoing autosense to
be moved onto the disconnected list. The bus reset handler must call
complete_cmd() for these commands, otherwise the hostdata->sensing pointer
will not get cleared. That would cause autosense processing to stall and
a timeout or an incorrect scsi_eh_restore_cmnd() would eventually follow.

Signed-off-by: Finn Thain <fthain@telegraphics.com.au>
Reported-by: Michael Schmitz <schmitzmic@gmail.com>
Tested-by: Ondrej Zary <linux@rainbow-software.org>
Reviewed-by: Hannes Reinecke <hare@suse.com>

---
 drivers/scsi/NCR5380.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

Index: linux/drivers/scsi/NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/NCR5380.c	2016-03-23 21:10:00.000000000 +1100
+++ linux/drivers/scsi/NCR5380.c	2016-03-23 21:10:07.000000000 +1100
@@ -2437,7 +2437,7 @@ static int NCR5380_bus_reset(struct scsi
 		struct scsi_cmnd *cmd = NCR5380_to_scmd(ncmd);
 
 		set_host_byte(cmd, DID_RESET);
-		cmd->scsi_done(cmd);
+		complete_cmd(instance, cmd);
 	}
 	INIT_LIST_HEAD(&hostdata->disconnected);
 



^ permalink raw reply	[flat|nested] 60+ messages in thread

* Re: [PATCH v4 00/23] ncr5380: Eliminate macros, reduce code duplication, fix bugs etc
  2016-03-23 10:10 ` Finn Thain
@ 2016-03-23 20:54   ` Martin K. Petersen
  -1 siblings, 0 replies; 60+ messages in thread
From: Martin K. Petersen @ 2016-03-23 20:54 UTC (permalink / raw)
  To: Finn Thain
  Cc: James E.J. Bottomley, Martin K. Petersen, Michael Schmitz,
	linux-m68k, linux-scsi, linux-kernel, Ondrej Zary, Sam Creasey

>>>>> "Finn" == Finn Thain <fthain@telegraphics.com.au> writes:

Finn,

Finn> This patch series has been tested on several platforms. I tested
Finn> the dmx3191d and mac_scsi modules on suitable hardware, Michael
Finn> tested atari_scsi on an Atari Falcon and Ondrej has tested
Finn> g_NCR5380 and g_NCR5380_mmio on various ISA cards.

Applied to 4.7/scsi-queue.

And thanks for re-posting with all the relevant tags applied. Much
appreciated!

-- 
Martin K. Petersen	Oracle Linux Engineering

^ permalink raw reply	[flat|nested] 60+ messages in thread

* Re: [PATCH v4 00/23] ncr5380: Eliminate macros, reduce code duplication, fix bugs etc
@ 2016-03-23 20:54   ` Martin K. Petersen
  0 siblings, 0 replies; 60+ messages in thread
From: Martin K. Petersen @ 2016-03-23 20:54 UTC (permalink / raw)
  To: Finn Thain
  Cc: James E.J. Bottomley, Martin K. Petersen, Michael Schmitz,
	linux-m68k, linux-scsi, linux-kernel, Ondrej Zary, Sam Creasey

>>>>> "Finn" == Finn Thain <fthain@telegraphics.com.au> writes:

Finn,

Finn> This patch series has been tested on several platforms. I tested
Finn> the dmx3191d and mac_scsi modules on suitable hardware, Michael
Finn> tested atari_scsi on an Atari Falcon and Ondrej has tested
Finn> g_NCR5380 and g_NCR5380_mmio on various ISA cards.

Applied to 4.7/scsi-queue.

And thanks for re-posting with all the relevant tags applied. Much
appreciated!

-- 
Martin K. Petersen	Oracle Linux Engineering

^ permalink raw reply	[flat|nested] 60+ messages in thread

* Re: [PATCH v4 22/23] mac_scsi: Fix pseudo DMA implementation
  2016-03-23 10:10   ` Finn Thain
@ 2016-05-19  9:00     ` Geert Uytterhoeven
  -1 siblings, 0 replies; 60+ messages in thread
From: Geert Uytterhoeven @ 2016-05-19  9:00 UTC (permalink / raw)
  To: Finn Thain
  Cc: James E.J. Bottomley, Martin K. Petersen, Michael Schmitz,
	Linux/m68k, scsi, linux-kernel, Ondrej Zary, Sam Creasey

Hi Finn,

On Wed, Mar 23, 2016 at 11:10 AM, Finn Thain <fthain@telegraphics.com.au> wrote:
> Fix various issues: Comments about bus errors are incorrect. The
> PDMA asm must return the size of the memory access that faulted so the
> transfer count can be adjusted accordingly. A phase change may cause a
> bus error but should not be treated as failure. A bus error does not
> always imply a phase change and generally the transfer may continue.
> Scatter/gather doesn't seem to work with PDMA due to overruns. This is
> a pity because peak throughput seems to double with SG_ALL.
> Tested on a Mac LC III and a PowerBook 520.
>
> Signed-off-by: Finn Thain <fthain@telegraphics.com.au>
> Reviewed-by: Hannes Reinecke <hare@suse.com>

> --- linux.orig/drivers/scsi/mac_scsi.c  2016-03-23 21:09:53.000000000 +1100
> +++ linux/drivers/scsi/mac_scsi.c       2016-03-23 21:10:05.000000000 +1100

> @@ -104,18 +105,9 @@ static int __init mac_scsi_setup(char *s

>  static int macscsi_pread(struct Scsi_Host *instance,
>                           unsigned char *dst, int len)
>  {
>         struct NCR5380_hostdata *hostdata = shost_priv(instance);
> -       unsigned char *d;
> -       unsigned char *s;
> -
> -       s = hostdata->pdma_base + (INPUT_DATA_REG << 4);
> -       d = dst;
> -
> -       /* These conditions are derived from MacOS */
> -
> -       while (!(NCR5380_read(BUS_AND_STATUS_REG) & BASR_DRQ) &&
> -              !(NCR5380_read(STATUS_REG) & SR_REQ))
> -               ;
> -
> -       if (!(NCR5380_read(BUS_AND_STATUS_REG) & BASR_DRQ) &&
> -           (NCR5380_read(BUS_AND_STATUS_REG) & BASR_PHASE_MATCH)) {
> -               pr_err("Error in macscsi_pread\n");
> -               return -1;
> -       }
> -
> -       CP_IO_TO_MEM(s, d, len);
> -
> -       if (len != 0) {
> -               pr_notice("Bus error in macscsi_pread\n");
> -               return -1;
> +       unsigned char *s = hostdata->pdma_base + (INPUT_DATA_REG << 4);
> +       unsigned char *d = dst;
> +       int n = len;
> +       int transferred;
> +
> +       while (!NCR5380_poll_politely(instance, BUS_AND_STATUS_REG,
> +                                     BASR_DRQ | BASR_PHASE_MATCH,
> +                                     BASR_DRQ | BASR_PHASE_MATCH, HZ / 64)) {
> +               CP_IO_TO_MEM(s, d, n);

This is now before the inclusion of NCR5380.c, causing

In file included from drivers/scsi/mac_scsi.c:335:
drivers/scsi/NCR5380.h:295: warning: ‘NCR5380_poll_politely’ declared
inline after being called
drivers/scsi/NCR5380.h:295: warning: previous declaration of
‘NCR5380_poll_politely’ was here

Gr{oetje,eeting}s,

                        Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds

^ permalink raw reply	[flat|nested] 60+ messages in thread

* Re: [PATCH v4 22/23] mac_scsi: Fix pseudo DMA implementation
@ 2016-05-19  9:00     ` Geert Uytterhoeven
  0 siblings, 0 replies; 60+ messages in thread
From: Geert Uytterhoeven @ 2016-05-19  9:00 UTC (permalink / raw)
  To: Finn Thain
  Cc: James E.J. Bottomley, Martin K. Petersen, Michael Schmitz,
	Linux/m68k, scsi, linux-kernel, Ondrej Zary, Sam Creasey

Hi Finn,

On Wed, Mar 23, 2016 at 11:10 AM, Finn Thain <fthain@telegraphics.com.au> wrote:
> Fix various issues: Comments about bus errors are incorrect. The
> PDMA asm must return the size of the memory access that faulted so the
> transfer count can be adjusted accordingly. A phase change may cause a
> bus error but should not be treated as failure. A bus error does not
> always imply a phase change and generally the transfer may continue.
> Scatter/gather doesn't seem to work with PDMA due to overruns. This is
> a pity because peak throughput seems to double with SG_ALL.
> Tested on a Mac LC III and a PowerBook 520.
>
> Signed-off-by: Finn Thain <fthain@telegraphics.com.au>
> Reviewed-by: Hannes Reinecke <hare@suse.com>

> --- linux.orig/drivers/scsi/mac_scsi.c  2016-03-23 21:09:53.000000000 +1100
> +++ linux/drivers/scsi/mac_scsi.c       2016-03-23 21:10:05.000000000 +1100

> @@ -104,18 +105,9 @@ static int __init mac_scsi_setup(char *s

>  static int macscsi_pread(struct Scsi_Host *instance,
>                           unsigned char *dst, int len)
>  {
>         struct NCR5380_hostdata *hostdata = shost_priv(instance);
> -       unsigned char *d;
> -       unsigned char *s;
> -
> -       s = hostdata->pdma_base + (INPUT_DATA_REG << 4);
> -       d = dst;
> -
> -       /* These conditions are derived from MacOS */
> -
> -       while (!(NCR5380_read(BUS_AND_STATUS_REG) & BASR_DRQ) &&
> -              !(NCR5380_read(STATUS_REG) & SR_REQ))
> -               ;
> -
> -       if (!(NCR5380_read(BUS_AND_STATUS_REG) & BASR_DRQ) &&
> -           (NCR5380_read(BUS_AND_STATUS_REG) & BASR_PHASE_MATCH)) {
> -               pr_err("Error in macscsi_pread\n");
> -               return -1;
> -       }
> -
> -       CP_IO_TO_MEM(s, d, len);
> -
> -       if (len != 0) {
> -               pr_notice("Bus error in macscsi_pread\n");
> -               return -1;
> +       unsigned char *s = hostdata->pdma_base + (INPUT_DATA_REG << 4);
> +       unsigned char *d = dst;
> +       int n = len;
> +       int transferred;
> +
> +       while (!NCR5380_poll_politely(instance, BUS_AND_STATUS_REG,
> +                                     BASR_DRQ | BASR_PHASE_MATCH,
> +                                     BASR_DRQ | BASR_PHASE_MATCH, HZ / 64)) {
> +               CP_IO_TO_MEM(s, d, n);

This is now before the inclusion of NCR5380.c, causing

In file included from drivers/scsi/mac_scsi.c:335:
drivers/scsi/NCR5380.h:295: warning: ‘NCR5380_poll_politely’ declared
inline after being called
drivers/scsi/NCR5380.h:295: warning: previous declaration of
‘NCR5380_poll_politely’ was here

Gr{oetje,eeting}s,

                        Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds
--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 60+ messages in thread

* Re: [PATCH v4 22/23] mac_scsi: Fix pseudo DMA implementation
  2016-05-19  9:00     ` Geert Uytterhoeven
  (?)
@ 2016-05-19 12:02     ` Finn Thain
  2016-05-19 12:55       ` Geert Uytterhoeven
  -1 siblings, 1 reply; 60+ messages in thread
From: Finn Thain @ 2016-05-19 12:02 UTC (permalink / raw)
  To: Geert Uytterhoeven
  Cc: James E.J. Bottomley, Martin K. Petersen, Michael Schmitz,
	linux-m68k, linux-scsi, linux-kernel, Ondrej Zary, Sam Creasey


On Thu, 19 May 2016, Geert Uytterhoeven wrote:

> 
> In file included from drivers/scsi/mac_scsi.c:335:
> drivers/scsi/NCR5380.h:295: warning: `NCR5380_poll_politely' declared inline after being called
> drivers/scsi/NCR5380.h:295: warning: previous declaration of `NCR5380_poll_politely' was here

Thanks for letting me know. My compiler (v4.4.6) doesn't warn about this. 
What GCC version are you using? Does this (untested) patch help?

Index: linux/drivers/scsi/NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/NCR5380.c	2016-05-19 21:31:05.000000000 +1000
+++ linux/drivers/scsi/NCR5380.c	2016-05-19 21:39:08.000000000 +1000
@@ -230,13 +230,6 @@ static int NCR5380_poll_politely2(struct
 	return -ETIMEDOUT;
 }
 
-static inline int NCR5380_poll_politely(struct Scsi_Host *instance,
-                                        int reg, int bit, int val, int wait)
-{
-	return NCR5380_poll_politely2(instance, reg, bit, val,
-	                                        reg, bit, val, wait);
-}
-
 #if NDEBUG
 static struct {
 	unsigned char mask;
Index: linux/drivers/scsi/NCR5380.h
===================================================================
--- linux.orig/drivers/scsi/NCR5380.h	2016-05-19 19:47:06.000000000 +1000
+++ linux/drivers/scsi/NCR5380.h	2016-05-19 21:40:15.000000000 +1000
@@ -292,8 +292,10 @@ static void NCR5380_reselect(struct Scsi
 static struct scsi_cmnd *NCR5380_select(struct Scsi_Host *, struct scsi_cmnd *);
 static int NCR5380_transfer_dma(struct Scsi_Host *instance, unsigned char *phase, int *count, unsigned char **data);
 static int NCR5380_transfer_pio(struct Scsi_Host *instance, unsigned char *phase, int *count, unsigned char **data);
-static int NCR5380_poll_politely(struct Scsi_Host *, int, int, int, int);
 static int NCR5380_poll_politely2(struct Scsi_Host *, int, int, int, int, int, int, int);
 
+#define NCR5380_poll_politely(instance, reg, bit, val, wait) \
+        NCR5380_poll_politely2(instance, reg, bit, val, reg, bit, val, wait)
+
 #endif				/* __KERNEL__ */
 #endif				/* NCR5380_H */

-- 

^ permalink raw reply	[flat|nested] 60+ messages in thread

* Re: [PATCH v4 22/23] mac_scsi: Fix pseudo DMA implementation
  2016-05-19 12:02     ` Finn Thain
@ 2016-05-19 12:55       ` Geert Uytterhoeven
  0 siblings, 0 replies; 60+ messages in thread
From: Geert Uytterhoeven @ 2016-05-19 12:55 UTC (permalink / raw)
  To: Finn Thain
  Cc: James E.J. Bottomley, Martin K. Petersen, Michael Schmitz,
	Linux/m68k, scsi, linux-kernel, Ondrej Zary, Sam Creasey

Hi Finn,

On Thu, May 19, 2016 at 2:02 PM, Finn Thain <fthain@telegraphics.com.au> wrote:
> On Thu, 19 May 2016, Geert Uytterhoeven wrote:
>> In file included from drivers/scsi/mac_scsi.c:335:
>> drivers/scsi/NCR5380.h:295: warning: `NCR5380_poll_politely' declared inline after being called
>> drivers/scsi/NCR5380.h:295: warning: previous declaration of `NCR5380_poll_politely' was here
>
> Thanks for letting me know. My compiler (v4.4.6) doesn't warn about this.
> What GCC version are you using? Does this (untested) patch help?

The venerable gcc version 4.1.2 20061115 (prerelease) (Ubuntu 4.1.1-21).
Which seems to disobey __attribute__((unused)):

     drivers/scsi/NCR5380.c:385: warning: ‘NCR5380_probe_irq’ defined
but not used

> Index: linux/drivers/scsi/NCR5380.c
> ===================================================================
> --- linux.orig/drivers/scsi/NCR5380.c   2016-05-19 21:31:05.000000000 +1000
> +++ linux/drivers/scsi/NCR5380.c        2016-05-19 21:39:08.000000000 +1000
> @@ -230,13 +230,6 @@ static int NCR5380_poll_politely2(struct
>         return -ETIMEDOUT;
>  }
>
> -static inline int NCR5380_poll_politely(struct Scsi_Host *instance,
> -                                        int reg, int bit, int val, int wait)
> -{
> -       return NCR5380_poll_politely2(instance, reg, bit, val,
> -                                               reg, bit, val, wait);
> -}
> -
>  #if NDEBUG
>  static struct {
>         unsigned char mask;
> Index: linux/drivers/scsi/NCR5380.h
> ===================================================================
> --- linux.orig/drivers/scsi/NCR5380.h   2016-05-19 19:47:06.000000000 +1000
> +++ linux/drivers/scsi/NCR5380.h        2016-05-19 21:40:15.000000000 +1000
> @@ -292,8 +292,10 @@ static void NCR5380_reselect(struct Scsi
>  static struct scsi_cmnd *NCR5380_select(struct Scsi_Host *, struct scsi_cmnd *);
>  static int NCR5380_transfer_dma(struct Scsi_Host *instance, unsigned char *phase, int *count, unsigned char **data);
>  static int NCR5380_transfer_pio(struct Scsi_Host *instance, unsigned char *phase, int *count, unsigned char **data);
> -static int NCR5380_poll_politely(struct Scsi_Host *, int, int, int, int);
>  static int NCR5380_poll_politely2(struct Scsi_Host *, int, int, int, int, int, int, int);
>
> +#define NCR5380_poll_politely(instance, reg, bit, val, wait) \
> +        NCR5380_poll_politely2(instance, reg, bit, val, reg, bit, val, wait)

Thanks, that silences the warning.

BTW, what about using the static inline variant here? That works, too.

Gr{oetje,eeting}s,

                        Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds

^ permalink raw reply	[flat|nested] 60+ messages in thread

end of thread, other threads:[~2016-05-19 12:55 UTC | newest]

Thread overview: 60+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-03-23 10:10 [PATCH v4 00/23] ncr5380: Eliminate macros, reduce code duplication, fix bugs etc Finn Thain
2016-03-23 10:10 ` Finn Thain
2016-03-23 10:10 ` [PATCH v4 01/23] g_ncr5380: Remove CONFIG_SCSI_GENERIC_NCR53C400 Finn Thain
2016-03-23 10:10   ` Finn Thain
2016-03-23 10:10 ` [PATCH v4 02/23] ncr5380: Remove FLAG_NO_PSEUDO_DMA where possible Finn Thain
2016-03-23 10:10   ` Finn Thain
2016-03-23 10:10 ` [PATCH v4 03/23] ncr5380: Remove REAL_DMA and REAL_DMA_POLL macros Finn Thain
2016-03-23 10:10   ` Finn Thain
2016-03-23 10:10 ` [PATCH v4 04/23] atari_NCR5380: Remove DMA_MIN_SIZE macro Finn Thain
2016-03-23 10:10   ` Finn Thain
2016-03-23 10:10 ` [PATCH v4 05/23] ncr5380: Disable the DMA errata workaround flag by default Finn Thain
2016-03-23 10:10   ` Finn Thain
2016-03-23 10:10   ` Finn Thain
2016-03-23 10:10 ` [PATCH v4 06/23] ncr5380: Remove PSEUDO_DMA macro Finn Thain
2016-03-23 10:10   ` Finn Thain
2016-03-23 10:10   ` Finn Thain
2016-03-23 10:10 ` [PATCH v4 07/23] ncr5380: Remove BOARD_REQUIRES_NO_DELAY macro Finn Thain
2016-03-23 10:10   ` Finn Thain
2016-03-23 10:10 ` [PATCH v4 08/23] ncr5380: Use DMA hooks for PDMA Finn Thain
2016-03-23 10:10   ` Finn Thain
2016-03-23 10:10   ` Finn Thain
2016-03-23 10:10 ` [PATCH v4 09/23] ncr5380: Adopt uniform DMA setup convention Finn Thain
2016-03-23 10:10   ` Finn Thain
2016-03-23 10:10   ` Finn Thain
2016-03-23 10:10 ` [PATCH v4 10/23] ncr5380: Merge DMA implementation from atari_NCR5380 core driver Finn Thain
2016-03-23 10:10   ` Finn Thain
2016-03-23 10:10   ` Finn Thain
2016-03-23 10:10 ` [PATCH v4 11/23] atari_scsi: Adopt NCR5380.c " Finn Thain
2016-03-23 10:10   ` Finn Thain
2016-03-23 10:10 ` [PATCH v4 12/23] sun3_scsi: " Finn Thain
2016-03-23 10:10   ` Finn Thain
2016-03-23 10:10 ` [PATCH v4 13/23] ncr5380: Remove disused atari_NCR5380.c " Finn Thain
2016-03-23 10:10   ` Finn Thain
2016-03-23 10:10 ` [PATCH v4 14/23] ncr5380: Reduce max_lun limit Finn Thain
2016-03-23 10:10   ` Finn Thain
2016-03-23 10:10 ` [PATCH v4 15/23] dmx3191d: Drop max_sectors limit Finn Thain
2016-03-23 10:10   ` Finn Thain
2016-03-23 10:10 ` [PATCH v4 16/23] ncr5380: Fix register decoding for debugging Finn Thain
2016-03-23 10:10   ` Finn Thain
2016-03-23 10:10 ` [PATCH v4 17/23] ncr5380: Remove remaining register storage qualifiers Finn Thain
2016-03-23 10:10   ` Finn Thain
2016-03-23 10:10 ` [PATCH v4 18/23] ncr5380: Remove DONT_USE_INTR and AUTOPROBE_IRQ macros Finn Thain
2016-03-23 10:10   ` Finn Thain
2016-03-23 10:10   ` Finn Thain
2016-03-23 10:10 ` [PATCH v4 19/23] ncr5380: Update usage documentation Finn Thain
2016-03-23 10:10   ` Finn Thain
2016-03-23 10:10 ` [PATCH v4 20/23] atari_scsi: Set a reasonable default for cmd_per_lun Finn Thain
2016-03-23 10:10   ` Finn Thain
2016-03-23 10:10 ` [PATCH v4 21/23] atari_scsi: Allow can_queue to be increased for Falcon Finn Thain
2016-03-23 10:10   ` Finn Thain
2016-03-23 10:10 ` [PATCH v4 22/23] mac_scsi: Fix pseudo DMA implementation Finn Thain
2016-03-23 10:10   ` Finn Thain
2016-05-19  9:00   ` Geert Uytterhoeven
2016-05-19  9:00     ` Geert Uytterhoeven
2016-05-19 12:02     ` Finn Thain
2016-05-19 12:55       ` Geert Uytterhoeven
2016-03-23 10:10 ` [PATCH v4 23/23] ncr5380: Call complete_cmd() for disconnected commands on bus reset Finn Thain
2016-03-23 10:10   ` Finn Thain
2016-03-23 20:54 ` [PATCH v4 00/23] ncr5380: Eliminate macros, reduce code duplication, fix bugs etc Martin K. Petersen
2016-03-23 20:54   ` Martin K. Petersen

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.