All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 00/71] More fixes, cleanup and modernization for NCR5380 drivers
@ 2015-11-18  8:34 ` Finn Thain
  0 siblings, 0 replies; 268+ messages in thread
From: Finn Thain @ 2015-11-18  8:34 UTC (permalink / raw)
  To: James E.J. Bottomley, Michael Schmitz, linux-m68k, linux-scsi,
	linux-kernel


Like my previous work on the NCR5380 drivers, this patch series has bug
fixes, code cleanup and modernization. These drivers suffer from mistakes,
poor style and neglect and this long series addresses the worst of it,
covering all ten wrapper drivers and both of the core driver forks. The
combined size of the drivers is reduced by about 750 LoC.

This series continues to reduce divergence between the two core driver
forks, often by copying a bug fix from one to the other. Most patches are
larger for having to keep the two forks in sync. Making the same change to
both is churn if one of them is to be removed but neither can be as yet.
By the end of this series the diff between the two forks is minimal, so it
becomes clear what caused the fork and what can be done about it.

This patch series did benefit from scripts/checkpatch.pl but not too much.
Decades ago, these drivers started out with 4-space tabs and if the 80
column limit were to be strictly enforced now, it would require adding new
functions and shortening identifiers. I would defer this sort of activity
until after the fork has been resolved.

I have compile-tested all patches to all NCR5380 drivers (x86, ARM, m68k)
and regression tested mac_scsi and dmx3191d modules on suitable hardware.
Testing the mac_scsi and dmx3191d modules provides only limited coverage.
It would be good to see some testing of ISA cards and Sun 3 and Atari
hardware too (I don't have any).

---
 drivers/scsi/Kconfig         |   17 
 drivers/scsi/NCR5380.c       | 2871 +++++++++++++++++++------------------------
 drivers/scsi/NCR5380.h       |   72 -
 drivers/scsi/arm/cumana_1.c  |   30 
 drivers/scsi/arm/oak.c       |   26 
 drivers/scsi/atari_NCR5380.c | 2295 +++++++++++++++-------------------
 drivers/scsi/atari_scsi.c    |  102 -
 drivers/scsi/dmx3191d.c      |   32 
 drivers/scsi/dtc.c           |  114 -
 drivers/scsi/dtc.h           |   45 
 drivers/scsi/g_NCR5380.c     |  178 +-
 drivers/scsi/g_NCR5380.h     |   56 
 drivers/scsi/mac_scsi.c      |  116 -
 drivers/scsi/pas16.c         |  115 -
 drivers/scsi/pas16.h         |   40 
 drivers/scsi/sun3_scsi.c     |  141 --
 drivers/scsi/t128.c          |  101 -
 drivers/scsi/t128.h          |   39 
 18 files changed, 2815 insertions(+), 3575 deletions(-)





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

* [PATCH 00/71] More fixes, cleanup and modernization for NCR5380 drivers
@ 2015-11-18  8:34 ` Finn Thain
  0 siblings, 0 replies; 268+ messages in thread
From: Finn Thain @ 2015-11-18  8:34 UTC (permalink / raw)
  To: James E.J. Bottomley, Michael Schmitz, linux-m68k, linux-scsi,
	linux-kernel


Like my previous work on the NCR5380 drivers, this patch series has bug
fixes, code cleanup and modernization. These drivers suffer from mistakes,
poor style and neglect and this long series addresses the worst of it,
covering all ten wrapper drivers and both of the core driver forks. The
combined size of the drivers is reduced by about 750 LoC.

This series continues to reduce divergence between the two core driver
forks, often by copying a bug fix from one to the other. Most patches are
larger for having to keep the two forks in sync. Making the same change to
both is churn if one of them is to be removed but neither can be as yet.
By the end of this series the diff between the two forks is minimal, so it
becomes clear what caused the fork and what can be done about it.

This patch series did benefit from scripts/checkpatch.pl but not too much.
Decades ago, these drivers started out with 4-space tabs and if the 80
column limit were to be strictly enforced now, it would require adding new
functions and shortening identifiers. I would defer this sort of activity
until after the fork has been resolved.

I have compile-tested all patches to all NCR5380 drivers (x86, ARM, m68k)
and regression tested mac_scsi and dmx3191d modules on suitable hardware.
Testing the mac_scsi and dmx3191d modules provides only limited coverage.
It would be good to see some testing of ISA cards and Sun 3 and Atari
hardware too (I don't have any).

---
 drivers/scsi/Kconfig         |   17 
 drivers/scsi/NCR5380.c       | 2871 +++++++++++++++++++------------------------
 drivers/scsi/NCR5380.h       |   72 -
 drivers/scsi/arm/cumana_1.c  |   30 
 drivers/scsi/arm/oak.c       |   26 
 drivers/scsi/atari_NCR5380.c | 2295 +++++++++++++++-------------------
 drivers/scsi/atari_scsi.c    |  102 -
 drivers/scsi/dmx3191d.c      |   32 
 drivers/scsi/dtc.c           |  114 -
 drivers/scsi/dtc.h           |   45 
 drivers/scsi/g_NCR5380.c     |  178 +-
 drivers/scsi/g_NCR5380.h     |   56 
 drivers/scsi/mac_scsi.c      |  116 -
 drivers/scsi/pas16.c         |  115 -
 drivers/scsi/pas16.h         |   40 
 drivers/scsi/sun3_scsi.c     |  141 --
 drivers/scsi/t128.c          |  101 -
 drivers/scsi/t128.h          |   39 
 18 files changed, 2815 insertions(+), 3575 deletions(-)

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

* [PATCH 01/71] atari_scsi: Fix SCSI host ID setting
  2015-11-18  8:34 ` Finn Thain
@ 2015-11-18  8:34   ` Finn Thain
  -1 siblings, 0 replies; 268+ messages in thread
From: Finn Thain @ 2015-11-18  8:34 UTC (permalink / raw)
  To: James E.J. Bottomley, Michael Schmitz, linux-m68k, linux-scsi,
	linux-kernel

[-- Attachment #1: atari_scsi-fix-host-id --]
[-- Type: text/plain, Size: 1001 bytes --]

The NVRAM location of this byte is 16, as documented in
http://toshyp.atari.org/en/004009.html

This was confirmed by Michael Schmitz, by setting the SCSI host ID
under EmuTOS and then checking the value in /proc/driver/nvram and
/dev/nvram under Linux.

Signed-off-by: Finn Thain <fthain@telegraphics.com.au>

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

Index: linux/drivers/scsi/atari_scsi.c
===================================================================
--- linux.orig/drivers/scsi/atari_scsi.c	2015-11-18 19:25:56.000000000 +1100
+++ linux/drivers/scsi/atari_scsi.c	2015-11-18 19:32:58.000000000 +1100
@@ -880,7 +880,7 @@ static int __init atari_scsi_probe(struc
 	} else {
 		/* Test if a host id is set in the NVRam */
 		if (ATARIHW_PRESENT(TT_CLK) && nvram_check_checksum()) {
-			unsigned char b = nvram_read_byte(14);
+			unsigned char b = nvram_read_byte(16);
 
 			/* Arbitration enabled? (for TOS)
 			 * If yes, use configured host ID



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

* [PATCH 01/71] atari_scsi: Fix SCSI host ID setting
@ 2015-11-18  8:34   ` Finn Thain
  0 siblings, 0 replies; 268+ messages in thread
From: Finn Thain @ 2015-11-18  8:34 UTC (permalink / raw)
  To: James E.J. Bottomley, Michael Schmitz, linux-m68k, linux-scsi,
	linux-kernel

[-- Attachment #1: atari_scsi-fix-host-id --]
[-- Type: text/plain, Size: 999 bytes --]

The NVRAM location of this byte is 16, as documented in
http://toshyp.atari.org/en/004009.html

This was confirmed by Michael Schmitz, by setting the SCSI host ID
under EmuTOS and then checking the value in /proc/driver/nvram and
/dev/nvram under Linux.

Signed-off-by: Finn Thain <fthain@telegraphics.com.au>

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

Index: linux/drivers/scsi/atari_scsi.c
===================================================================
--- linux.orig/drivers/scsi/atari_scsi.c	2015-11-18 19:25:56.000000000 +1100
+++ linux/drivers/scsi/atari_scsi.c	2015-11-18 19:32:58.000000000 +1100
@@ -880,7 +880,7 @@ static int __init atari_scsi_probe(struc
 	} else {
 		/* Test if a host id is set in the NVRam */
 		if (ATARIHW_PRESENT(TT_CLK) && nvram_check_checksum()) {
-			unsigned char b = nvram_read_byte(14);
+			unsigned char b = nvram_read_byte(16);
 
 			/* Arbitration enabled? (for TOS)
 			 * If yes, use configured host ID

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

* [PATCH 02/71] ncr5380: Remove redundant static variable initializers
  2015-11-18  8:34 ` Finn Thain
@ 2015-11-18  8:34   ` Finn Thain
  -1 siblings, 0 replies; 268+ messages in thread
From: Finn Thain @ 2015-11-18  8:34 UTC (permalink / raw)
  To: James E.J. Bottomley, Michael Schmitz, linux-m68k, linux-scsi,
	linux-kernel

[-- Attachment #1: ncr5380-remove-redundant-static-initializers --]
[-- Type: text/plain, Size: 4853 bytes --]

Signed-off-by: Finn Thain <fthain@telegraphics.com.au>

---
 drivers/scsi/NCR5380.c   |    2 +-
 drivers/scsi/dtc.c       |    4 ++--
 drivers/scsi/g_NCR5380.c |    4 ++--
 drivers/scsi/pas16.c     |   10 +++++-----
 drivers/scsi/sun3_scsi.c |    8 ++++----
 drivers/scsi/t128.c      |    4 ++--
 6 files changed, 16 insertions(+), 16 deletions(-)

Index: linux/drivers/scsi/NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/NCR5380.c	2015-11-18 19:25:56.000000000 +1100
+++ linux/drivers/scsi/NCR5380.c	2015-11-18 19:32:59.000000000 +1100
@@ -534,7 +534,7 @@ static void NCR5380_set_timer(struct NCR
 }
 
 
-static int probe_irq __initdata = 0;
+static int probe_irq __initdata;
 
 /**
  *	probe_intr	-	helper for IRQ autoprobe
Index: linux/drivers/scsi/dtc.c
===================================================================
--- linux.orig/drivers/scsi/dtc.c	2015-11-18 19:25:56.000000000 +1100
+++ linux/drivers/scsi/dtc.c	2015-11-18 19:32:59.000000000 +1100
@@ -150,7 +150,7 @@ static const struct signature {
 
 static int __init dtc_setup(char *str)
 {
-	static int commandline_current = 0;
+	static int commandline_current;
 	int i;
 	int ints[10];
 
@@ -188,7 +188,7 @@ __setup("dtc=", dtc_setup);
 
 static int __init dtc_detect(struct scsi_host_template * tpnt)
 {
-	static int current_override = 0, current_base = 0;
+	static int current_override, current_base;
 	struct Scsi_Host *instance;
 	unsigned int addr;
 	void __iomem *base;
Index: linux/drivers/scsi/g_NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/g_NCR5380.c	2015-11-18 19:25:56.000000000 +1100
+++ linux/drivers/scsi/g_NCR5380.c	2015-11-18 19:32:59.000000000 +1100
@@ -121,7 +121,7 @@ static struct override {
 
 static void __init internal_setup(int board, char *str, int *ints)
 {
-	static int commandline_current = 0;
+	static int commandline_current;
 	switch (board) {
 	case BOARD_NCR5380:
 		if (ints[0] != 2 && ints[0] != 3) {
@@ -251,7 +251,7 @@ static int __init do_DTC3181E_setup(char
 
 static int __init generic_NCR5380_detect(struct scsi_host_template *tpnt)
 {
-	static int current_override = 0;
+	static int current_override;
 	int count;
 	unsigned int *ports;
 #ifndef SCSI_G_NCR5380_MEM
Index: linux/drivers/scsi/pas16.c
===================================================================
--- linux.orig/drivers/scsi/pas16.c	2015-11-18 19:25:56.000000000 +1100
+++ linux/drivers/scsi/pas16.c	2015-11-18 19:32:59.000000000 +1100
@@ -87,8 +87,8 @@
 #include "NCR5380.h"
 
 
-static unsigned short pas16_addr = 0;
-static int pas16_irq = 0;
+static unsigned short pas16_addr;
+static int pas16_irq;
  
 
 static const int scsi_irq_translate[] =
@@ -305,7 +305,7 @@ static int __init
 
 static int __init pas16_setup(char *str)
 {
-    static int commandline_current = 0;
+	static int commandline_current;
     int i;
     int ints[10];
 
@@ -344,8 +344,8 @@ __setup("pas16=", pas16_setup);
 
 static int __init pas16_detect(struct scsi_host_template *tpnt)
 {
-    static int current_override = 0;
-    static unsigned short current_base = 0;
+	static int current_override;
+	static unsigned short current_base;
     struct Scsi_Host *instance;
     unsigned short io_port;
     int  count;
Index: linux/drivers/scsi/sun3_scsi.c
===================================================================
--- linux.orig/drivers/scsi/sun3_scsi.c	2015-11-18 19:25:56.000000000 +1100
+++ linux/drivers/scsi/sun3_scsi.c	2015-11-18 19:32:59.000000000 +1100
@@ -100,10 +100,10 @@ static struct scsi_cmnd *sun3_dma_setup_
 static unsigned char *sun3_scsi_regp;
 static volatile struct sun3_dma_regs *dregs;
 static struct sun3_udc_regs *udc_regs;
-static unsigned char *sun3_dma_orig_addr = NULL;
-static unsigned long sun3_dma_orig_count = 0;
-static int sun3_dma_active = 0;
-static unsigned long last_residual = 0;
+static unsigned char *sun3_dma_orig_addr;
+static unsigned long sun3_dma_orig_count;
+static int sun3_dma_active;
+static unsigned long last_residual;
 static struct Scsi_Host *default_instance;
 
 /*
Index: linux/drivers/scsi/t128.c
===================================================================
--- linux.orig/drivers/scsi/t128.c	2015-11-18 19:25:56.000000000 +1100
+++ linux/drivers/scsi/t128.c	2015-11-18 19:32:59.000000000 +1100
@@ -126,7 +126,7 @@ static struct signature {
 
 static int __init t128_setup(char *str)
 {
-    static int commandline_current = 0;
+	static int commandline_current;
     int i;
     int ints[10];
 
@@ -165,7 +165,7 @@ __setup("t128=", t128_setup);
 
 static int __init t128_detect(struct scsi_host_template *tpnt)
 {
-    static int current_override = 0, current_base = 0;
+	static int current_override, current_base;
     struct Scsi_Host *instance;
     unsigned long base;
     void __iomem *p;



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

* [PATCH 02/71] ncr5380: Remove redundant static variable initializers
@ 2015-11-18  8:34   ` Finn Thain
  0 siblings, 0 replies; 268+ messages in thread
From: Finn Thain @ 2015-11-18  8:34 UTC (permalink / raw)
  To: James E.J. Bottomley, Michael Schmitz, linux-m68k, linux-scsi,
	linux-kernel

[-- Attachment #1: ncr5380-remove-redundant-static-initializers --]
[-- Type: text/plain, Size: 4851 bytes --]

Signed-off-by: Finn Thain <fthain@telegraphics.com.au>

---
 drivers/scsi/NCR5380.c   |    2 +-
 drivers/scsi/dtc.c       |    4 ++--
 drivers/scsi/g_NCR5380.c |    4 ++--
 drivers/scsi/pas16.c     |   10 +++++-----
 drivers/scsi/sun3_scsi.c |    8 ++++----
 drivers/scsi/t128.c      |    4 ++--
 6 files changed, 16 insertions(+), 16 deletions(-)

Index: linux/drivers/scsi/NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/NCR5380.c	2015-11-18 19:25:56.000000000 +1100
+++ linux/drivers/scsi/NCR5380.c	2015-11-18 19:32:59.000000000 +1100
@@ -534,7 +534,7 @@ static void NCR5380_set_timer(struct NCR
 }
 
 
-static int probe_irq __initdata = 0;
+static int probe_irq __initdata;
 
 /**
  *	probe_intr	-	helper for IRQ autoprobe
Index: linux/drivers/scsi/dtc.c
===================================================================
--- linux.orig/drivers/scsi/dtc.c	2015-11-18 19:25:56.000000000 +1100
+++ linux/drivers/scsi/dtc.c	2015-11-18 19:32:59.000000000 +1100
@@ -150,7 +150,7 @@ static const struct signature {
 
 static int __init dtc_setup(char *str)
 {
-	static int commandline_current = 0;
+	static int commandline_current;
 	int i;
 	int ints[10];
 
@@ -188,7 +188,7 @@ __setup("dtc=", dtc_setup);
 
 static int __init dtc_detect(struct scsi_host_template * tpnt)
 {
-	static int current_override = 0, current_base = 0;
+	static int current_override, current_base;
 	struct Scsi_Host *instance;
 	unsigned int addr;
 	void __iomem *base;
Index: linux/drivers/scsi/g_NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/g_NCR5380.c	2015-11-18 19:25:56.000000000 +1100
+++ linux/drivers/scsi/g_NCR5380.c	2015-11-18 19:32:59.000000000 +1100
@@ -121,7 +121,7 @@ static struct override {
 
 static void __init internal_setup(int board, char *str, int *ints)
 {
-	static int commandline_current = 0;
+	static int commandline_current;
 	switch (board) {
 	case BOARD_NCR5380:
 		if (ints[0] != 2 && ints[0] != 3) {
@@ -251,7 +251,7 @@ static int __init do_DTC3181E_setup(char
 
 static int __init generic_NCR5380_detect(struct scsi_host_template *tpnt)
 {
-	static int current_override = 0;
+	static int current_override;
 	int count;
 	unsigned int *ports;
 #ifndef SCSI_G_NCR5380_MEM
Index: linux/drivers/scsi/pas16.c
===================================================================
--- linux.orig/drivers/scsi/pas16.c	2015-11-18 19:25:56.000000000 +1100
+++ linux/drivers/scsi/pas16.c	2015-11-18 19:32:59.000000000 +1100
@@ -87,8 +87,8 @@
 #include "NCR5380.h"
 
 
-static unsigned short pas16_addr = 0;
-static int pas16_irq = 0;
+static unsigned short pas16_addr;
+static int pas16_irq;
  
 
 static const int scsi_irq_translate[] =
@@ -305,7 +305,7 @@ static int __init
 
 static int __init pas16_setup(char *str)
 {
-    static int commandline_current = 0;
+	static int commandline_current;
     int i;
     int ints[10];
 
@@ -344,8 +344,8 @@ __setup("pas16=", pas16_setup);
 
 static int __init pas16_detect(struct scsi_host_template *tpnt)
 {
-    static int current_override = 0;
-    static unsigned short current_base = 0;
+	static int current_override;
+	static unsigned short current_base;
     struct Scsi_Host *instance;
     unsigned short io_port;
     int  count;
Index: linux/drivers/scsi/sun3_scsi.c
===================================================================
--- linux.orig/drivers/scsi/sun3_scsi.c	2015-11-18 19:25:56.000000000 +1100
+++ linux/drivers/scsi/sun3_scsi.c	2015-11-18 19:32:59.000000000 +1100
@@ -100,10 +100,10 @@ static struct scsi_cmnd *sun3_dma_setup_
 static unsigned char *sun3_scsi_regp;
 static volatile struct sun3_dma_regs *dregs;
 static struct sun3_udc_regs *udc_regs;
-static unsigned char *sun3_dma_orig_addr = NULL;
-static unsigned long sun3_dma_orig_count = 0;
-static int sun3_dma_active = 0;
-static unsigned long last_residual = 0;
+static unsigned char *sun3_dma_orig_addr;
+static unsigned long sun3_dma_orig_count;
+static int sun3_dma_active;
+static unsigned long last_residual;
 static struct Scsi_Host *default_instance;
 
 /*
Index: linux/drivers/scsi/t128.c
===================================================================
--- linux.orig/drivers/scsi/t128.c	2015-11-18 19:25:56.000000000 +1100
+++ linux/drivers/scsi/t128.c	2015-11-18 19:32:59.000000000 +1100
@@ -126,7 +126,7 @@ static struct signature {
 
 static int __init t128_setup(char *str)
 {
-    static int commandline_current = 0;
+	static int commandline_current;
     int i;
     int ints[10];
 
@@ -165,7 +165,7 @@ __setup("t128=", t128_setup);
 
 static int __init t128_detect(struct scsi_host_template *tpnt)
 {
-    static int current_override = 0, current_base = 0;
+	static int current_override, current_base;
     struct Scsi_Host *instance;
     unsigned long base;
     void __iomem *p;

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

* [PATCH 03/71] ncr5380: Eliminate PDEBUG*, TDEBUG* and DTCDEBUG* macros
  2015-11-18  8:34 ` Finn Thain
@ 2015-11-18  8:34   ` Finn Thain
  -1 siblings, 0 replies; 268+ messages in thread
From: Finn Thain @ 2015-11-18  8:34 UTC (permalink / raw)
  To: James E.J. Bottomley, Michael Schmitz, linux-m68k, linux-scsi,
	linux-kernel

[-- Attachment #1: ncr5380-remove-TDEBUG-DTCDEBUG-PDEBUG --]
[-- Type: text/plain, Size: 9976 bytes --]

Replace {P,T,DTC}DEBUG_INIT with NDEBUG_INIT. Remove dead debugging
code, including code that's conditional upon *DEBUG_TRANSFER.

Signed-off-by: Finn Thain <fthain@telegraphics.com.au>

---
 drivers/scsi/dtc.c   |   18 ++++++------------
 drivers/scsi/dtc.h   |   27 ---------------------------
 drivers/scsi/pas16.c |   21 +++++++--------------
 drivers/scsi/pas16.h |   16 ----------------
 drivers/scsi/t128.c  |   18 ++++++------------
 drivers/scsi/t128.h  |   16 ----------------
 6 files changed, 19 insertions(+), 97 deletions(-)

Index: linux/drivers/scsi/dtc.c
===================================================================
--- linux.orig/drivers/scsi/dtc.c	2015-11-18 19:32:59.000000000 +1100
+++ linux/drivers/scsi/dtc.c	2015-11-18 19:33:02.000000000 +1100
@@ -205,9 +205,8 @@ static int __init dtc_detect(struct scsi
 				addr = 0;
 		} else
 			for (; !addr && (current_base < NO_BASES); ++current_base) {
-#if (DTCDEBUG & DTCDEBUG_INIT)
-				printk(KERN_DEBUG "scsi-dtc : probing address %08x\n", bases[current_base].address);
-#endif
+				dprintk(NDEBUG_INIT, "dtc: probing address 0x%08x\n",
+				        (unsigned int)bases[current_base].address);
 				if (bases[current_base].noauto)
 					continue;
 				base = ioremap(bases[current_base].address, 0x2000);
@@ -216,18 +215,14 @@ static int __init dtc_detect(struct scsi
 				for (sig = 0; sig < NO_SIGNATURES; ++sig) {
 					if (check_signature(base + signatures[sig].offset, signatures[sig].string, strlen(signatures[sig].string))) {
 						addr = bases[current_base].address;
-#if (DTCDEBUG & DTCDEBUG_INIT)
-						printk(KERN_DEBUG "scsi-dtc : detected board.\n");
-#endif
+						dprintk(NDEBUG_INIT, "dtc: detected board\n");
 						goto found;
 					}
 				}
 				iounmap(base);
 			}
 
-#if defined(DTCDEBUG) && (DTCDEBUG & DTCDEBUG_INIT)
-		printk(KERN_DEBUG "scsi-dtc : base = %08x\n", addr);
-#endif
+		dprintk(NDEBUG_INIT, "dtc: addr = 0x%08x\n", addr);
 
 		if (!addr)
 			break;
@@ -271,9 +266,8 @@ found:
 			printk(KERN_WARNING "scsi%d : interrupts not used. Might as well not jumper it.\n", instance->host_no);
 		instance->irq = NO_IRQ;
 #endif
-#if defined(DTCDEBUG) && (DTCDEBUG & DTCDEBUG_INIT)
-		printk("scsi%d : irq = %d\n", instance->host_no, instance->irq);
-#endif
+		dprintk(NDEBUG_INIT, "scsi%d : irq = %d\n",
+		        instance->host_no, instance->irq);
 
 		++current_override;
 		++count;
Index: linux/drivers/scsi/dtc.h
===================================================================
--- linux.orig/drivers/scsi/dtc.h	2015-11-18 19:25:56.000000000 +1100
+++ linux/drivers/scsi/dtc.h	2015-11-18 19:33:02.000000000 +1100
@@ -10,10 +10,6 @@
 #ifndef DTC3280_H
 #define DTC3280_H
 
-#define DTCDEBUG 0
-#define DTCDEBUG_INIT	0x1
-#define DTCDEBUG_TRANSFER 0x2
-
 #ifndef CMD_PER_LUN
 #define CMD_PER_LUN 2
 #endif
@@ -33,31 +29,8 @@
 
 #define DTC_address(reg) (base + DTC_5380_OFFSET + reg)
 
-#define dbNCR5380_read(reg)                                              \
-    (rval=readb(DTC_address(reg)), \
-     (((unsigned char) printk("DTC : read register %d at addr %p is: %02x\n"\
-    , (reg), DTC_address(reg), rval)), rval ) )
-
-#define dbNCR5380_write(reg, value) do {                                  \
-    printk("DTC : write %02x to register %d at address %p\n",         \
-            (value), (reg), DTC_address(reg));     \
-    writeb(value, DTC_address(reg));} while(0)
-
-
-#if !(DTCDEBUG & DTCDEBUG_TRANSFER) 
 #define NCR5380_read(reg) (readb(DTC_address(reg)))
 #define NCR5380_write(reg, value) (writeb(value, DTC_address(reg)))
-#else
-#define NCR5380_read(reg) (readb(DTC_address(reg)))
-#define xNCR5380_read(reg)						\
-    (((unsigned char) printk("DTC : read register %d at address %p\n"\
-    , (reg), DTC_address(reg))), readb(DTC_address(reg)))
-
-#define NCR5380_write(reg, value) do {					\
-    printk("DTC : write %02x to register %d at address %p\n", 	\
-	    (value), (reg), DTC_address(reg));	\
-    writeb(value, DTC_address(reg));} while(0)
-#endif
 
 #define NCR5380_intr			dtc_intr
 #define NCR5380_queue_command		dtc_queue_command
Index: linux/drivers/scsi/pas16.c
===================================================================
--- linux.orig/drivers/scsi/pas16.c	2015-11-18 19:32:59.000000000 +1100
+++ linux/drivers/scsi/pas16.c	2015-11-18 19:33:02.000000000 +1100
@@ -1,6 +1,5 @@
 #define PSEUDO_DMA
 #define UNSAFE  /* Not unsafe for PAS16 -- use it */
-#define PDEBUG 0
 
 /*
  * This driver adapted from Drew Eckhardt's Trantor T128 driver
@@ -377,23 +376,18 @@ static int __init pas16_detect(struct sc
 	}
 	else
 	    for (; !io_port && (current_base < NO_BASES); ++current_base) {
-#if (PDEBUG & PDEBUG_INIT)
-    printk("scsi-pas16 : probing io_port %04x\n", (unsigned int) bases[current_base].io_port);
-#endif
+		dprintk(NDEBUG_INIT, "pas16: probing io_port 0x%04x\n",
+		        (unsigned int)bases[current_base].io_port);
 		if ( !bases[current_base].noauto &&
 		     pas16_hw_detect( current_base ) ){
 			io_port = bases[current_base].io_port;
 			init_board( io_port, default_irqs[ current_base ], 0 ); 
-#if (PDEBUG & PDEBUG_INIT)
-			printk("scsi-pas16 : detected board.\n");
-#endif
+			dprintk(NDEBUG_INIT, "pas16: detected board\n");
 		}
     }
 
-
-#if defined(PDEBUG) && (PDEBUG & PDEBUG_INIT)
-	printk("scsi-pas16 : io_port = %04x\n", (unsigned int) io_port);
-#endif
+	dprintk(NDEBUG_INIT, "pas16: io_port = 0x%04x\n",
+	        (unsigned int)io_port);
 
 	if (!io_port)
 	    break;
@@ -431,9 +425,8 @@ static int __init pas16_detect(struct sc
 	    outb( (inb(io_port + IO_CONFIG_3) & 0x0f), io_port + IO_CONFIG_3 );
 	}
 
-#if defined(PDEBUG) && (PDEBUG & PDEBUG_INIT)
-	printk("scsi%d : irq = %d\n", instance->host_no, instance->irq);
-#endif
+	dprintk(NDEBUG_INIT, "scsi%d : irq = %d\n",
+	        instance->host_no, instance->irq);
 
 	++current_override;
 	++count;
Index: linux/drivers/scsi/pas16.h
===================================================================
--- linux.orig/drivers/scsi/pas16.h	2015-11-18 19:25:56.000000000 +1100
+++ linux/drivers/scsi/pas16.h	2015-11-18 19:33:02.000000000 +1100
@@ -24,9 +24,6 @@
 #ifndef PAS16_H
 #define PAS16_H
 
-#define PDEBUG_INIT	0x1
-#define PDEBUG_TRANSFER 0x2
-
 #define PAS16_DEFAULT_BASE_1  0x388
 #define PAS16_DEFAULT_BASE_2  0x384
 #define PAS16_DEFAULT_BASE_3  0x38c
@@ -120,21 +117,8 @@
 
 #define PAS16_io_port(reg) ( io_port + pas16_offset[(reg)] )
 
-#if !(PDEBUG & PDEBUG_TRANSFER) 
 #define NCR5380_read(reg) ( inb(PAS16_io_port(reg)) )
 #define NCR5380_write(reg, value) ( outb((value),PAS16_io_port(reg)) )
-#else
-#define NCR5380_read(reg)						\
-    (((unsigned char) printk("scsi%d : read register %d at io_port %04x\n"\
-    , instance->hostno, (reg), PAS16_io_port(reg))), inb( PAS16_io_port(reg)) )
-
-#define NCR5380_write(reg, value) 					\
-    (printk("scsi%d : write %02x to register %d at io_port %04x\n", 	\
-	    instance->hostno, (value), (reg), PAS16_io_port(reg)),	\
-    outb( (value),PAS16_io_port(reg) ) )
-
-#endif
-
 
 #define NCR5380_intr pas16_intr
 #define do_NCR5380_intr do_pas16_intr
Index: linux/drivers/scsi/t128.c
===================================================================
--- linux.orig/drivers/scsi/t128.c	2015-11-18 19:32:59.000000000 +1100
+++ linux/drivers/scsi/t128.c	2015-11-18 19:33:02.000000000 +1100
@@ -182,9 +182,8 @@ static int __init t128_detect(struct scs
 		base = 0;
 	} else 
 	    for (; !base && (current_base < NO_BASES); ++current_base) {
-#if (TDEBUG & TDEBUG_INIT)
-    printk("scsi-t128 : probing address %08x\n", bases[current_base].address);
-#endif
+		dprintk(NDEBUG_INIT, "t128: probing address 0x%08x\n",
+		        bases[current_base].address);
 		if (bases[current_base].noauto)
 			continue;
 		p = ioremap(bases[current_base].address, 0x2000);
@@ -195,17 +194,13 @@ static int __init t128_detect(struct scs
 					signatures[sig].string,
 					strlen(signatures[sig].string))) {
 			base = bases[current_base].address;
-#if (TDEBUG & TDEBUG_INIT)
-			printk("scsi-t128 : detected board.\n");
-#endif
+			dprintk(NDEBUG_INIT, "t128: detected board\n");
 			goto found;
 		    }
 		iounmap(p);
 	    }
 
-#if defined(TDEBUG) && (TDEBUG & TDEBUG_INIT)
-	printk("scsi-t128 : base = %08x\n", (unsigned int) base);
-#endif
+	dprintk(NDEBUG_INIT, "t128: base = 0x%08x\n", (unsigned int)base);
 
 	if (!base)
 	    break;
@@ -242,9 +237,8 @@ found:
 	    printk("scsi%d : please jumper the board for a free IRQ.\n", instance->host_no);
 	}
 
-#if defined(TDEBUG) && (TDEBUG & TDEBUG_INIT)
-	printk("scsi%d : irq = %d\n", instance->host_no, instance->irq);
-#endif
+	dprintk(NDEBUG_INIT, "scsi%d: irq = %d\n",
+	        instance->host_no, instance->irq);
 
 	++current_override;
 	++count;
Index: linux/drivers/scsi/t128.h
===================================================================
--- linux.orig/drivers/scsi/t128.h	2015-11-18 19:25:56.000000000 +1100
+++ linux/drivers/scsi/t128.h	2015-11-18 19:33:02.000000000 +1100
@@ -23,10 +23,6 @@
 #ifndef T128_H
 #define T128_H
 
-#define TDEBUG		0
-#define TDEBUG_INIT	0x1
-#define TDEBUG_TRANSFER 0x2
-
 /*
  * The trantor boards are memory mapped. They use an NCR5380 or
  * equivalent (my sample board had part second sourced from ZILOG).
@@ -92,20 +88,8 @@
 
 #define T128_address(reg) (base + T_5380_OFFSET + ((reg) * 0x20))
 
-#if !(TDEBUG & TDEBUG_TRANSFER)
 #define NCR5380_read(reg) readb(T128_address(reg))
 #define NCR5380_write(reg, value) writeb((value),(T128_address(reg)))
-#else
-#define NCR5380_read(reg)						\
-    (((unsigned char) printk("scsi%d : read register %d at address %08x\n"\
-    , instance->hostno, (reg), T128_address(reg))), readb(T128_address(reg)))
-
-#define NCR5380_write(reg, value) {					\
-    printk("scsi%d : write %02x to register %d at address %08x\n",	\
-	    instance->hostno, (value), (reg), T128_address(reg));	\
-    writeb((value), (T128_address(reg)));				\
-}
-#endif
 
 #define NCR5380_intr t128_intr
 #define do_NCR5380_intr do_t128_intr



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

* [PATCH 03/71] ncr5380: Eliminate PDEBUG*, TDEBUG* and DTCDEBUG* macros
@ 2015-11-18  8:34   ` Finn Thain
  0 siblings, 0 replies; 268+ messages in thread
From: Finn Thain @ 2015-11-18  8:34 UTC (permalink / raw)
  To: James E.J. Bottomley, Michael Schmitz, linux-m68k, linux-scsi,
	linux-kernel

[-- Attachment #1: ncr5380-remove-TDEBUG-DTCDEBUG-PDEBUG --]
[-- Type: text/plain, Size: 9974 bytes --]

Replace {P,T,DTC}DEBUG_INIT with NDEBUG_INIT. Remove dead debugging
code, including code that's conditional upon *DEBUG_TRANSFER.

Signed-off-by: Finn Thain <fthain@telegraphics.com.au>

---
 drivers/scsi/dtc.c   |   18 ++++++------------
 drivers/scsi/dtc.h   |   27 ---------------------------
 drivers/scsi/pas16.c |   21 +++++++--------------
 drivers/scsi/pas16.h |   16 ----------------
 drivers/scsi/t128.c  |   18 ++++++------------
 drivers/scsi/t128.h  |   16 ----------------
 6 files changed, 19 insertions(+), 97 deletions(-)

Index: linux/drivers/scsi/dtc.c
===================================================================
--- linux.orig/drivers/scsi/dtc.c	2015-11-18 19:32:59.000000000 +1100
+++ linux/drivers/scsi/dtc.c	2015-11-18 19:33:02.000000000 +1100
@@ -205,9 +205,8 @@ static int __init dtc_detect(struct scsi
 				addr = 0;
 		} else
 			for (; !addr && (current_base < NO_BASES); ++current_base) {
-#if (DTCDEBUG & DTCDEBUG_INIT)
-				printk(KERN_DEBUG "scsi-dtc : probing address %08x\n", bases[current_base].address);
-#endif
+				dprintk(NDEBUG_INIT, "dtc: probing address 0x%08x\n",
+				        (unsigned int)bases[current_base].address);
 				if (bases[current_base].noauto)
 					continue;
 				base = ioremap(bases[current_base].address, 0x2000);
@@ -216,18 +215,14 @@ static int __init dtc_detect(struct scsi
 				for (sig = 0; sig < NO_SIGNATURES; ++sig) {
 					if (check_signature(base + signatures[sig].offset, signatures[sig].string, strlen(signatures[sig].string))) {
 						addr = bases[current_base].address;
-#if (DTCDEBUG & DTCDEBUG_INIT)
-						printk(KERN_DEBUG "scsi-dtc : detected board.\n");
-#endif
+						dprintk(NDEBUG_INIT, "dtc: detected board\n");
 						goto found;
 					}
 				}
 				iounmap(base);
 			}
 
-#if defined(DTCDEBUG) && (DTCDEBUG & DTCDEBUG_INIT)
-		printk(KERN_DEBUG "scsi-dtc : base = %08x\n", addr);
-#endif
+		dprintk(NDEBUG_INIT, "dtc: addr = 0x%08x\n", addr);
 
 		if (!addr)
 			break;
@@ -271,9 +266,8 @@ found:
 			printk(KERN_WARNING "scsi%d : interrupts not used. Might as well not jumper it.\n", instance->host_no);
 		instance->irq = NO_IRQ;
 #endif
-#if defined(DTCDEBUG) && (DTCDEBUG & DTCDEBUG_INIT)
-		printk("scsi%d : irq = %d\n", instance->host_no, instance->irq);
-#endif
+		dprintk(NDEBUG_INIT, "scsi%d : irq = %d\n",
+		        instance->host_no, instance->irq);
 
 		++current_override;
 		++count;
Index: linux/drivers/scsi/dtc.h
===================================================================
--- linux.orig/drivers/scsi/dtc.h	2015-11-18 19:25:56.000000000 +1100
+++ linux/drivers/scsi/dtc.h	2015-11-18 19:33:02.000000000 +1100
@@ -10,10 +10,6 @@
 #ifndef DTC3280_H
 #define DTC3280_H
 
-#define DTCDEBUG 0
-#define DTCDEBUG_INIT	0x1
-#define DTCDEBUG_TRANSFER 0x2
-
 #ifndef CMD_PER_LUN
 #define CMD_PER_LUN 2
 #endif
@@ -33,31 +29,8 @@
 
 #define DTC_address(reg) (base + DTC_5380_OFFSET + reg)
 
-#define dbNCR5380_read(reg)                                              \
-    (rval=readb(DTC_address(reg)), \
-     (((unsigned char) printk("DTC : read register %d at addr %p is: %02x\n"\
-    , (reg), DTC_address(reg), rval)), rval ) )
-
-#define dbNCR5380_write(reg, value) do {                                  \
-    printk("DTC : write %02x to register %d at address %p\n",         \
-            (value), (reg), DTC_address(reg));     \
-    writeb(value, DTC_address(reg));} while(0)
-
-
-#if !(DTCDEBUG & DTCDEBUG_TRANSFER) 
 #define NCR5380_read(reg) (readb(DTC_address(reg)))
 #define NCR5380_write(reg, value) (writeb(value, DTC_address(reg)))
-#else
-#define NCR5380_read(reg) (readb(DTC_address(reg)))
-#define xNCR5380_read(reg)						\
-    (((unsigned char) printk("DTC : read register %d at address %p\n"\
-    , (reg), DTC_address(reg))), readb(DTC_address(reg)))
-
-#define NCR5380_write(reg, value) do {					\
-    printk("DTC : write %02x to register %d at address %p\n", 	\
-	    (value), (reg), DTC_address(reg));	\
-    writeb(value, DTC_address(reg));} while(0)
-#endif
 
 #define NCR5380_intr			dtc_intr
 #define NCR5380_queue_command		dtc_queue_command
Index: linux/drivers/scsi/pas16.c
===================================================================
--- linux.orig/drivers/scsi/pas16.c	2015-11-18 19:32:59.000000000 +1100
+++ linux/drivers/scsi/pas16.c	2015-11-18 19:33:02.000000000 +1100
@@ -1,6 +1,5 @@
 #define PSEUDO_DMA
 #define UNSAFE  /* Not unsafe for PAS16 -- use it */
-#define PDEBUG 0
 
 /*
  * This driver adapted from Drew Eckhardt's Trantor T128 driver
@@ -377,23 +376,18 @@ static int __init pas16_detect(struct sc
 	}
 	else
 	    for (; !io_port && (current_base < NO_BASES); ++current_base) {
-#if (PDEBUG & PDEBUG_INIT)
-    printk("scsi-pas16 : probing io_port %04x\n", (unsigned int) bases[current_base].io_port);
-#endif
+		dprintk(NDEBUG_INIT, "pas16: probing io_port 0x%04x\n",
+		        (unsigned int)bases[current_base].io_port);
 		if ( !bases[current_base].noauto &&
 		     pas16_hw_detect( current_base ) ){
 			io_port = bases[current_base].io_port;
 			init_board( io_port, default_irqs[ current_base ], 0 ); 
-#if (PDEBUG & PDEBUG_INIT)
-			printk("scsi-pas16 : detected board.\n");
-#endif
+			dprintk(NDEBUG_INIT, "pas16: detected board\n");
 		}
     }
 
-
-#if defined(PDEBUG) && (PDEBUG & PDEBUG_INIT)
-	printk("scsi-pas16 : io_port = %04x\n", (unsigned int) io_port);
-#endif
+	dprintk(NDEBUG_INIT, "pas16: io_port = 0x%04x\n",
+	        (unsigned int)io_port);
 
 	if (!io_port)
 	    break;
@@ -431,9 +425,8 @@ static int __init pas16_detect(struct sc
 	    outb( (inb(io_port + IO_CONFIG_3) & 0x0f), io_port + IO_CONFIG_3 );
 	}
 
-#if defined(PDEBUG) && (PDEBUG & PDEBUG_INIT)
-	printk("scsi%d : irq = %d\n", instance->host_no, instance->irq);
-#endif
+	dprintk(NDEBUG_INIT, "scsi%d : irq = %d\n",
+	        instance->host_no, instance->irq);
 
 	++current_override;
 	++count;
Index: linux/drivers/scsi/pas16.h
===================================================================
--- linux.orig/drivers/scsi/pas16.h	2015-11-18 19:25:56.000000000 +1100
+++ linux/drivers/scsi/pas16.h	2015-11-18 19:33:02.000000000 +1100
@@ -24,9 +24,6 @@
 #ifndef PAS16_H
 #define PAS16_H
 
-#define PDEBUG_INIT	0x1
-#define PDEBUG_TRANSFER 0x2
-
 #define PAS16_DEFAULT_BASE_1  0x388
 #define PAS16_DEFAULT_BASE_2  0x384
 #define PAS16_DEFAULT_BASE_3  0x38c
@@ -120,21 +117,8 @@
 
 #define PAS16_io_port(reg) ( io_port + pas16_offset[(reg)] )
 
-#if !(PDEBUG & PDEBUG_TRANSFER) 
 #define NCR5380_read(reg) ( inb(PAS16_io_port(reg)) )
 #define NCR5380_write(reg, value) ( outb((value),PAS16_io_port(reg)) )
-#else
-#define NCR5380_read(reg)						\
-    (((unsigned char) printk("scsi%d : read register %d at io_port %04x\n"\
-    , instance->hostno, (reg), PAS16_io_port(reg))), inb( PAS16_io_port(reg)) )
-
-#define NCR5380_write(reg, value) 					\
-    (printk("scsi%d : write %02x to register %d at io_port %04x\n", 	\
-	    instance->hostno, (value), (reg), PAS16_io_port(reg)),	\
-    outb( (value),PAS16_io_port(reg) ) )
-
-#endif
-
 
 #define NCR5380_intr pas16_intr
 #define do_NCR5380_intr do_pas16_intr
Index: linux/drivers/scsi/t128.c
===================================================================
--- linux.orig/drivers/scsi/t128.c	2015-11-18 19:32:59.000000000 +1100
+++ linux/drivers/scsi/t128.c	2015-11-18 19:33:02.000000000 +1100
@@ -182,9 +182,8 @@ static int __init t128_detect(struct scs
 		base = 0;
 	} else 
 	    for (; !base && (current_base < NO_BASES); ++current_base) {
-#if (TDEBUG & TDEBUG_INIT)
-    printk("scsi-t128 : probing address %08x\n", bases[current_base].address);
-#endif
+		dprintk(NDEBUG_INIT, "t128: probing address 0x%08x\n",
+		        bases[current_base].address);
 		if (bases[current_base].noauto)
 			continue;
 		p = ioremap(bases[current_base].address, 0x2000);
@@ -195,17 +194,13 @@ static int __init t128_detect(struct scs
 					signatures[sig].string,
 					strlen(signatures[sig].string))) {
 			base = bases[current_base].address;
-#if (TDEBUG & TDEBUG_INIT)
-			printk("scsi-t128 : detected board.\n");
-#endif
+			dprintk(NDEBUG_INIT, "t128: detected board\n");
 			goto found;
 		    }
 		iounmap(p);
 	    }
 
-#if defined(TDEBUG) && (TDEBUG & TDEBUG_INIT)
-	printk("scsi-t128 : base = %08x\n", (unsigned int) base);
-#endif
+	dprintk(NDEBUG_INIT, "t128: base = 0x%08x\n", (unsigned int)base);
 
 	if (!base)
 	    break;
@@ -242,9 +237,8 @@ found:
 	    printk("scsi%d : please jumper the board for a free IRQ.\n", instance->host_no);
 	}
 
-#if defined(TDEBUG) && (TDEBUG & TDEBUG_INIT)
-	printk("scsi%d : irq = %d\n", instance->host_no, instance->irq);
-#endif
+	dprintk(NDEBUG_INIT, "scsi%d: irq = %d\n",
+	        instance->host_no, instance->irq);
 
 	++current_override;
 	++count;
Index: linux/drivers/scsi/t128.h
===================================================================
--- linux.orig/drivers/scsi/t128.h	2015-11-18 19:25:56.000000000 +1100
+++ linux/drivers/scsi/t128.h	2015-11-18 19:33:02.000000000 +1100
@@ -23,10 +23,6 @@
 #ifndef T128_H
 #define T128_H
 
-#define TDEBUG		0
-#define TDEBUG_INIT	0x1
-#define TDEBUG_TRANSFER 0x2
-
 /*
  * The trantor boards are memory mapped. They use an NCR5380 or
  * equivalent (my sample board had part second sourced from ZILOG).
@@ -92,20 +88,8 @@
 
 #define T128_address(reg) (base + T_5380_OFFSET + ((reg) * 0x20))
 
-#if !(TDEBUG & TDEBUG_TRANSFER)
 #define NCR5380_read(reg) readb(T128_address(reg))
 #define NCR5380_write(reg, value) writeb((value),(T128_address(reg)))
-#else
-#define NCR5380_read(reg)						\
-    (((unsigned char) printk("scsi%d : read register %d at address %08x\n"\
-    , instance->hostno, (reg), T128_address(reg))), readb(T128_address(reg)))
-
-#define NCR5380_write(reg, value) {					\
-    printk("scsi%d : write %02x to register %d at address %08x\n",	\
-	    instance->hostno, (value), (reg), T128_address(reg));	\
-    writeb((value), (T128_address(reg)));				\
-}
-#endif
 
 #define NCR5380_intr t128_intr
 #define do_NCR5380_intr do_t128_intr

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

* [PATCH 04/71] ncr5380: Remove more pointless macros
  2015-11-18  8:34 ` Finn Thain
@ 2015-11-18  8:34   ` Finn Thain
  -1 siblings, 0 replies; 268+ messages in thread
From: Finn Thain @ 2015-11-18  8:34 UTC (permalink / raw)
  To: James E.J. Bottomley, Michael Schmitz, linux-m68k, linux-scsi,
	linux-kernel

[-- Attachment #1: ncr5380-remove-pointless-macros --]
[-- Type: text/plain, Size: 6150 bytes --]

ASM macro is never defined. rtrc in pas16.c is not used.
NCR5380_map_config, do_NCR5380_intr, do_t128_intr and do_pas16_intr
are unused. NCR_NOT_SET harms readability. Remove them.

Signed-off-by: Finn Thain <fthain@telegraphics.com.au>

---
 drivers/scsi/NCR5380.h   |    3 ---
 drivers/scsi/g_NCR5380.c |   29 ++++++++++++++---------------
 drivers/scsi/g_NCR5380.h |    5 -----
 drivers/scsi/pas16.c     |   16 ----------------
 drivers/scsi/pas16.h     |    5 -----
 drivers/scsi/t128.h      |    4 ----
 6 files changed, 14 insertions(+), 48 deletions(-)

Index: linux/drivers/scsi/NCR5380.h
===================================================================
--- linux.orig/drivers/scsi/NCR5380.h	2015-11-18 19:25:56.000000000 +1100
+++ linux/drivers/scsi/NCR5380.h	2015-11-18 19:33:04.000000000 +1100
@@ -244,8 +244,6 @@
 #define FLAG_LATE_DMA_SETUP		32	/* Setup NCR before DMA H/W */
 #define FLAG_TAGGED_QUEUING		64	/* as X3T9.2 spelled it */
 
-#ifndef ASM
-
 #ifdef SUPPORT_TAGS
 struct tag_alloc {
 	DECLARE_BITMAP(allocated, MAX_TAGS);
@@ -443,5 +441,4 @@ static __inline__ int NCR5380_pc_dma_res
 #endif				/* defined(i386) || defined(__alpha__) */
 #endif				/* defined(REAL_DMA)  */
 #endif				/* __KERNEL__ */
-#endif				/* ndef ASM */
 #endif				/* NCR5380_H */
Index: linux/drivers/scsi/g_NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/g_NCR5380.c	2015-11-18 19:32:59.000000000 +1100
+++ linux/drivers/scsi/g_NCR5380.c	2015-11-18 19:33:04.000000000 +1100
@@ -82,14 +82,13 @@
 #include <linux/delay.h>
 #include <linux/interrupt.h>
 
-#define NCR_NOT_SET 0
-static int ncr_irq = NCR_NOT_SET;
-static int ncr_dma = NCR_NOT_SET;
-static int ncr_addr = NCR_NOT_SET;
-static int ncr_5380 = NCR_NOT_SET;
-static int ncr_53c400 = NCR_NOT_SET;
-static int ncr_53c400a = NCR_NOT_SET;
-static int dtc_3181e = NCR_NOT_SET;
+static int ncr_irq;
+static int ncr_dma;
+static int ncr_addr;
+static int ncr_5380;
+static int ncr_53c400;
+static int ncr_53c400a;
+static int dtc_3181e;
 
 static struct override {
 	NCR5380_map_type NCR5380_map_name;
@@ -271,19 +270,19 @@ static int __init generic_NCR5380_detect
 	void __iomem *iomem;
 #endif
 
-	if (ncr_irq != NCR_NOT_SET)
+	if (ncr_irq)
 		overrides[0].irq = ncr_irq;
-	if (ncr_dma != NCR_NOT_SET)
+	if (ncr_dma)
 		overrides[0].dma = ncr_dma;
-	if (ncr_addr != NCR_NOT_SET)
+	if (ncr_addr)
 		overrides[0].NCR5380_map_name = (NCR5380_map_type) ncr_addr;
-	if (ncr_5380 != NCR_NOT_SET)
+	if (ncr_5380)
 		overrides[0].board = BOARD_NCR5380;
-	else if (ncr_53c400 != NCR_NOT_SET)
+	else if (ncr_53c400)
 		overrides[0].board = BOARD_NCR53C400;
-	else if (ncr_53c400a != NCR_NOT_SET)
+	else if (ncr_53c400a)
 		overrides[0].board = BOARD_NCR53C400A;
-	else if (dtc_3181e != NCR_NOT_SET)
+	else if (dtc_3181e)
 		overrides[0].board = BOARD_DTC3181E;
 #ifndef SCSI_G_NCR5380_MEM
 	if (!current_override && isapnp_present()) {
Index: linux/drivers/scsi/g_NCR5380.h
===================================================================
--- linux.orig/drivers/scsi/g_NCR5380.h	2015-11-18 19:25:56.000000000 +1100
+++ linux/drivers/scsi/g_NCR5380.h	2015-11-18 19:33:04.000000000 +1100
@@ -21,8 +21,6 @@
 #define NCR5380_BIOSPARAM NULL
 #endif
 
-#ifndef ASM
-
 #ifndef CMD_PER_LUN
 #define CMD_PER_LUN 2
 #endif
@@ -36,7 +34,6 @@
 
 #ifndef SCSI_G_NCR5380_MEM
 
-#define NCR5380_map_config port
 #define NCR5380_map_type int
 #define NCR5380_map_name port
 #define NCR5380_instance_name io_port
@@ -64,7 +61,6 @@
 #else 
 /* therefore SCSI_G_NCR5380_MEM */
 
-#define NCR5380_map_config memory
 #define NCR5380_map_type unsigned long
 #define NCR5380_map_name base
 #define NCR5380_instance_name base
@@ -103,6 +99,5 @@
 #define BOARD_NCR53C400A 2
 #define BOARD_DTC3181E	3
 
-#endif /* ndef ASM */
 #endif /* GENERIC_NCR5380_H */
 
Index: linux/drivers/scsi/pas16.c
===================================================================
--- linux.orig/drivers/scsi/pas16.c	2015-11-18 19:33:02.000000000 +1100
+++ linux/drivers/scsi/pas16.c	2015-11-18 19:33:04.000000000 +1100
@@ -145,22 +145,6 @@ static const unsigned short  pas16_offse
 		    * START_DMA_INITIATOR_RECEIVE_REG wo
 		    */
     };
-/*----------------------------------------------------------------*/
-/* the following will set the monitor border color (useful to find
- where something crashed or gets stuck at */
-/* 1 = blue
- 2 = green
- 3 = cyan
- 4 = red
- 5 = magenta
- 6 = yellow
- 7 = white
-*/
-#if 1
-#define rtrc(i) {inb(0x3da); outb(0x31, 0x3c0); outb((i), 0x3c0);}
-#else
-#define rtrc(i) {}
-#endif
 
 
 /*
Index: linux/drivers/scsi/pas16.h
===================================================================
--- linux.orig/drivers/scsi/pas16.h	2015-11-18 19:33:02.000000000 +1100
+++ linux/drivers/scsi/pas16.h	2015-11-18 19:33:04.000000000 +1100
@@ -95,9 +95,6 @@
 #define OPERATION_MODE_1 0xec03
 #define IO_CONFIG_3 0xf002
 
-
-#ifndef ASM
-
 #ifndef CMD_PER_LUN
 #define CMD_PER_LUN 2
 #endif
@@ -121,7 +118,6 @@
 #define NCR5380_write(reg, value) ( outb((value),PAS16_io_port(reg)) )
 
 #define NCR5380_intr pas16_intr
-#define do_NCR5380_intr do_pas16_intr
 #define NCR5380_queue_command pas16_queue_command
 #define NCR5380_abort pas16_abort
 #define NCR5380_bus_reset pas16_bus_reset
@@ -134,5 +130,4 @@
    
 #define PAS16_IRQS 0xd4a8 
 
-#endif /* ndef ASM */
 #endif /* PAS16_H */
Index: linux/drivers/scsi/t128.h
===================================================================
--- linux.orig/drivers/scsi/t128.h	2015-11-18 19:33:02.000000000 +1100
+++ linux/drivers/scsi/t128.h	2015-11-18 19:33:04.000000000 +1100
@@ -67,8 +67,6 @@
 
 #define T_DATA_REG_OFFSET	0x1e00	/* rw 512 bytes long */
 
-#ifndef ASM
-
 #ifndef CMD_PER_LUN
 #define CMD_PER_LUN 2
 #endif
@@ -92,7 +90,6 @@
 #define NCR5380_write(reg, value) writeb((value),(T128_address(reg)))
 
 #define NCR5380_intr t128_intr
-#define do_NCR5380_intr do_t128_intr
 #define NCR5380_queue_command t128_queue_command
 #define NCR5380_abort t128_abort
 #define NCR5380_bus_reset t128_bus_reset
@@ -105,5 +102,4 @@
 
 #define T128_IRQS 0xc4a8
 
-#endif /* ndef ASM */
 #endif /* T128_H */



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

* [PATCH 04/71] ncr5380: Remove more pointless macros
@ 2015-11-18  8:34   ` Finn Thain
  0 siblings, 0 replies; 268+ messages in thread
From: Finn Thain @ 2015-11-18  8:34 UTC (permalink / raw)
  To: James E.J. Bottomley, Michael Schmitz, linux-m68k, linux-scsi,
	linux-kernel

[-- Attachment #1: ncr5380-remove-pointless-macros --]
[-- Type: text/plain, Size: 6148 bytes --]

ASM macro is never defined. rtrc in pas16.c is not used.
NCR5380_map_config, do_NCR5380_intr, do_t128_intr and do_pas16_intr
are unused. NCR_NOT_SET harms readability. Remove them.

Signed-off-by: Finn Thain <fthain@telegraphics.com.au>

---
 drivers/scsi/NCR5380.h   |    3 ---
 drivers/scsi/g_NCR5380.c |   29 ++++++++++++++---------------
 drivers/scsi/g_NCR5380.h |    5 -----
 drivers/scsi/pas16.c     |   16 ----------------
 drivers/scsi/pas16.h     |    5 -----
 drivers/scsi/t128.h      |    4 ----
 6 files changed, 14 insertions(+), 48 deletions(-)

Index: linux/drivers/scsi/NCR5380.h
===================================================================
--- linux.orig/drivers/scsi/NCR5380.h	2015-11-18 19:25:56.000000000 +1100
+++ linux/drivers/scsi/NCR5380.h	2015-11-18 19:33:04.000000000 +1100
@@ -244,8 +244,6 @@
 #define FLAG_LATE_DMA_SETUP		32	/* Setup NCR before DMA H/W */
 #define FLAG_TAGGED_QUEUING		64	/* as X3T9.2 spelled it */
 
-#ifndef ASM
-
 #ifdef SUPPORT_TAGS
 struct tag_alloc {
 	DECLARE_BITMAP(allocated, MAX_TAGS);
@@ -443,5 +441,4 @@ static __inline__ int NCR5380_pc_dma_res
 #endif				/* defined(i386) || defined(__alpha__) */
 #endif				/* defined(REAL_DMA)  */
 #endif				/* __KERNEL__ */
-#endif				/* ndef ASM */
 #endif				/* NCR5380_H */
Index: linux/drivers/scsi/g_NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/g_NCR5380.c	2015-11-18 19:32:59.000000000 +1100
+++ linux/drivers/scsi/g_NCR5380.c	2015-11-18 19:33:04.000000000 +1100
@@ -82,14 +82,13 @@
 #include <linux/delay.h>
 #include <linux/interrupt.h>
 
-#define NCR_NOT_SET 0
-static int ncr_irq = NCR_NOT_SET;
-static int ncr_dma = NCR_NOT_SET;
-static int ncr_addr = NCR_NOT_SET;
-static int ncr_5380 = NCR_NOT_SET;
-static int ncr_53c400 = NCR_NOT_SET;
-static int ncr_53c400a = NCR_NOT_SET;
-static int dtc_3181e = NCR_NOT_SET;
+static int ncr_irq;
+static int ncr_dma;
+static int ncr_addr;
+static int ncr_5380;
+static int ncr_53c400;
+static int ncr_53c400a;
+static int dtc_3181e;
 
 static struct override {
 	NCR5380_map_type NCR5380_map_name;
@@ -271,19 +270,19 @@ static int __init generic_NCR5380_detect
 	void __iomem *iomem;
 #endif
 
-	if (ncr_irq != NCR_NOT_SET)
+	if (ncr_irq)
 		overrides[0].irq = ncr_irq;
-	if (ncr_dma != NCR_NOT_SET)
+	if (ncr_dma)
 		overrides[0].dma = ncr_dma;
-	if (ncr_addr != NCR_NOT_SET)
+	if (ncr_addr)
 		overrides[0].NCR5380_map_name = (NCR5380_map_type) ncr_addr;
-	if (ncr_5380 != NCR_NOT_SET)
+	if (ncr_5380)
 		overrides[0].board = BOARD_NCR5380;
-	else if (ncr_53c400 != NCR_NOT_SET)
+	else if (ncr_53c400)
 		overrides[0].board = BOARD_NCR53C400;
-	else if (ncr_53c400a != NCR_NOT_SET)
+	else if (ncr_53c400a)
 		overrides[0].board = BOARD_NCR53C400A;
-	else if (dtc_3181e != NCR_NOT_SET)
+	else if (dtc_3181e)
 		overrides[0].board = BOARD_DTC3181E;
 #ifndef SCSI_G_NCR5380_MEM
 	if (!current_override && isapnp_present()) {
Index: linux/drivers/scsi/g_NCR5380.h
===================================================================
--- linux.orig/drivers/scsi/g_NCR5380.h	2015-11-18 19:25:56.000000000 +1100
+++ linux/drivers/scsi/g_NCR5380.h	2015-11-18 19:33:04.000000000 +1100
@@ -21,8 +21,6 @@
 #define NCR5380_BIOSPARAM NULL
 #endif
 
-#ifndef ASM
-
 #ifndef CMD_PER_LUN
 #define CMD_PER_LUN 2
 #endif
@@ -36,7 +34,6 @@
 
 #ifndef SCSI_G_NCR5380_MEM
 
-#define NCR5380_map_config port
 #define NCR5380_map_type int
 #define NCR5380_map_name port
 #define NCR5380_instance_name io_port
@@ -64,7 +61,6 @@
 #else 
 /* therefore SCSI_G_NCR5380_MEM */
 
-#define NCR5380_map_config memory
 #define NCR5380_map_type unsigned long
 #define NCR5380_map_name base
 #define NCR5380_instance_name base
@@ -103,6 +99,5 @@
 #define BOARD_NCR53C400A 2
 #define BOARD_DTC3181E	3
 
-#endif /* ndef ASM */
 #endif /* GENERIC_NCR5380_H */
 
Index: linux/drivers/scsi/pas16.c
===================================================================
--- linux.orig/drivers/scsi/pas16.c	2015-11-18 19:33:02.000000000 +1100
+++ linux/drivers/scsi/pas16.c	2015-11-18 19:33:04.000000000 +1100
@@ -145,22 +145,6 @@ static const unsigned short  pas16_offse
 		    * START_DMA_INITIATOR_RECEIVE_REG wo
 		    */
     };
-/*----------------------------------------------------------------*/
-/* the following will set the monitor border color (useful to find
- where something crashed or gets stuck at */
-/* 1 = blue
- 2 = green
- 3 = cyan
- 4 = red
- 5 = magenta
- 6 = yellow
- 7 = white
-*/
-#if 1
-#define rtrc(i) {inb(0x3da); outb(0x31, 0x3c0); outb((i), 0x3c0);}
-#else
-#define rtrc(i) {}
-#endif
 
 
 /*
Index: linux/drivers/scsi/pas16.h
===================================================================
--- linux.orig/drivers/scsi/pas16.h	2015-11-18 19:33:02.000000000 +1100
+++ linux/drivers/scsi/pas16.h	2015-11-18 19:33:04.000000000 +1100
@@ -95,9 +95,6 @@
 #define OPERATION_MODE_1 0xec03
 #define IO_CONFIG_3 0xf002
 
-
-#ifndef ASM
-
 #ifndef CMD_PER_LUN
 #define CMD_PER_LUN 2
 #endif
@@ -121,7 +118,6 @@
 #define NCR5380_write(reg, value) ( outb((value),PAS16_io_port(reg)) )
 
 #define NCR5380_intr pas16_intr
-#define do_NCR5380_intr do_pas16_intr
 #define NCR5380_queue_command pas16_queue_command
 #define NCR5380_abort pas16_abort
 #define NCR5380_bus_reset pas16_bus_reset
@@ -134,5 +130,4 @@
    
 #define PAS16_IRQS 0xd4a8 
 
-#endif /* ndef ASM */
 #endif /* PAS16_H */
Index: linux/drivers/scsi/t128.h
===================================================================
--- linux.orig/drivers/scsi/t128.h	2015-11-18 19:33:02.000000000 +1100
+++ linux/drivers/scsi/t128.h	2015-11-18 19:33:04.000000000 +1100
@@ -67,8 +67,6 @@
 
 #define T_DATA_REG_OFFSET	0x1e00	/* rw 512 bytes long */
 
-#ifndef ASM
-
 #ifndef CMD_PER_LUN
 #define CMD_PER_LUN 2
 #endif
@@ -92,7 +90,6 @@
 #define NCR5380_write(reg, value) writeb((value),(T128_address(reg)))
 
 #define NCR5380_intr t128_intr
-#define do_NCR5380_intr do_t128_intr
 #define NCR5380_queue_command t128_queue_command
 #define NCR5380_abort t128_abort
 #define NCR5380_bus_reset t128_bus_reset
@@ -105,5 +102,4 @@
 
 #define T128_IRQS 0xc4a8
 
-#endif /* ndef ASM */
 #endif /* T128_H */

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

* [PATCH 05/71] ncr5380: Remove NCR5380_local_declare and NCR5380_setup macros
  2015-11-18  8:34 ` Finn Thain
  (?)
@ 2015-11-18  8:35   ` Finn Thain
  -1 siblings, 0 replies; 268+ messages in thread
From: Finn Thain @ 2015-11-18  8:35 UTC (permalink / raw)
  To: James E.J. Bottomley, Michael Schmitz, linux-m68k, linux-scsi,
	linux-kernel, Russell King, linux-arm-kernel

[-- Attachment #1: ncr5380-eliminate-local_declare-macros --]
[-- Type: text/plain, Size: 28567 bytes --]

The NCR5380_local_declare and NCR5380_setup macros exist to define and
initialize a particular local variable, to provide the address of the
chip registers needed for the driver's implementation of its
NCR5380_read/write register access macros.

In cumana_1 and macscsi, these macros generate pointless code like this,
	struct Scsi_Host *_instance;
	_instance = instance;

In pas16, the use of NCR5380_read/write in pas16_hw_detect() requires that
the io_port local variable has been defined and initialized, but the
NCR5380_local_declare and NCR5380_setup macros can't be used for that
purpose because the Scsi_Host struct has not yet been instantiated.

Moreover, these macros were removed from atari_NCR5380.c long ago and
now they constitute yet another discrepancy between the two core driver
forks.

Remove these "optimizations".

Signed-off-by: Finn Thain <fthain@telegraphics.com.au>

---

Any performance penalty is highly unlikely given the algorithms involved
and the improvements made to compilers over the last two decades. (And
I'd probably accept some loss anyway given the maintainability benefit.)

Following the example of atari_NCR5380.c, the Scsi_Host pointer is now
always named "instance", and the NCR5380_read/write macros depend on this.
I think it is poor style to hard-code the identifier "instance" in these
macros but it is actually an improvement -- previously each NCR5380 driver
named a different local variable in its macro definitions.

Eventually, the NCR5380_read/write macros may have to become function
calls if this is to become a platform driver or a library. The instance
pointer or hostdata pointer will then have to be passed as an argument.

This patch is a step in that direction, in that it rewrites the
NCR5380_read/write macros in terms of hostdata and removes the
NCR5380_read/write usage from pas16_hw_detect() where there is no
Scsi_Host instance as yet.

---
 drivers/scsi/NCR5380.c      |   60 ++++++--------------------------------------
 drivers/scsi/arm/cumana_1.c |    6 +---
 drivers/scsi/arm/oak.c      |    9 +++---
 drivers/scsi/dmx3191d.c     |    6 +---
 drivers/scsi/dtc.c          |   14 +++-------
 drivers/scsi/dtc.h          |    9 +-----
 drivers/scsi/g_NCR5380.c    |   27 ++++++++++---------
 drivers/scsi/g_NCR5380.h    |   30 ++++++++--------------
 drivers/scsi/mac_scsi.c     |   15 +----------
 drivers/scsi/pas16.c        |   16 +++++------
 drivers/scsi/pas16.h        |   11 +-------
 drivers/scsi/t128.c         |   26 +++++++++----------
 drivers/scsi/t128.h         |    9 +-----
 13 files changed, 77 insertions(+), 161 deletions(-)

Index: linux/drivers/scsi/NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/NCR5380.c	2015-11-18 19:32:59.000000000 +1100
+++ linux/drivers/scsi/NCR5380.c	2015-11-18 19:33:05.000000000 +1100
@@ -230,11 +230,6 @@
  * USLEEP_POLL - amount of time, in jiffies, to poll
  *
  * These macros MUST be defined :
- * NCR5380_local_declare() - declare any local variables needed for your
- *      transfer routines.
- *
- * NCR5380_setup(instance) - initialize any local variables needed from a given
- *      instance of the host adapter for NCR5380_{read,write,pread,pwrite}
  * 
  * NCR5380_read(register)  - read from the specified register
  *
@@ -267,8 +262,8 @@
  * possible) function may be used.
  */
 
-static int do_abort(struct Scsi_Host *host);
-static void do_reset(struct Scsi_Host *host);
+static int do_abort(struct Scsi_Host *);
+static void do_reset(struct Scsi_Host *);
 
 /*
  *	initialize_SCp		-	init the scsi pointer field
@@ -313,12 +308,9 @@ static inline void initialize_SCp(struct
  
 static int NCR5380_poll_politely(struct Scsi_Host *instance, int reg, int bit, int val, int t)
 {
-	NCR5380_local_declare();
 	int n = 500;		/* At about 8uS a cycle for the cpu access */
 	unsigned long end = jiffies + t;
 	int r;
-	
-	NCR5380_setup(instance);
 
 	while( n-- > 0)
 	{
@@ -406,9 +398,7 @@ mrs[] = {
 
 static void NCR5380_print(struct Scsi_Host *instance)
 {
-	NCR5380_local_declare();
 	unsigned char status, data, basr, mr, icr, i;
-	NCR5380_setup(instance);
 
 	data = NCR5380_read(CURRENT_SCSI_DATA_REG);
 	status = NCR5380_read(STATUS_REG);
@@ -447,10 +437,8 @@ static void NCR5380_print(struct Scsi_Ho
 
 static void NCR5380_print_phase(struct Scsi_Host *instance)
 {
-	NCR5380_local_declare();
 	unsigned char status;
 	int i;
-	NCR5380_setup(instance);
 
 	status = NCR5380_read(STATUS_REG);
 	if (!(status & SR_REQ))
@@ -566,11 +554,9 @@ static irqreturn_t __init probe_intr(int
 static int __init __maybe_unused NCR5380_probe_irq(struct Scsi_Host *instance,
 						int possible)
 {
-	NCR5380_local_declare();
 	struct NCR5380_hostdata *hostdata = (struct NCR5380_hostdata *) instance->hostdata;
 	unsigned long timeout;
 	int trying_irqs, i, mask;
-	NCR5380_setup(instance);
 
 	for (trying_irqs = 0, i = 1, mask = 2; i < 16; ++i, mask <<= 1)
 		if ((mask & possible) && (request_irq(i, &probe_intr, 0, "NCR-probe", NULL) == 0))
@@ -791,7 +777,6 @@ static void lprint_opcode(int opcode, st
 
 static int NCR5380_init(struct Scsi_Host *instance, int flags)
 {
-	NCR5380_local_declare();
 	int i, pass;
 	unsigned long timeout;
 	struct NCR5380_hostdata *hostdata = (struct NCR5380_hostdata *) instance->hostdata;
@@ -808,8 +793,6 @@ static int NCR5380_init(struct Scsi_Host
 		instance->NCR5380_instance_name += NCR53C400_address_adjust;
 #endif
 
-	NCR5380_setup(instance);
-
 	hostdata->aborted = 0;
 	hostdata->id_mask = 1 << instance->this_id;
 	for (i = hostdata->id_mask; i <= 0x80; i <<= 1)
@@ -1100,7 +1083,6 @@ static void NCR5380_main(struct work_str
 
 static irqreturn_t NCR5380_intr(int dummy, void *dev_id)
 {
-	NCR5380_local_declare();
 	struct Scsi_Host *instance = dev_id;
 	struct NCR5380_hostdata *hostdata = (struct NCR5380_hostdata *) instance->hostdata;
 	int done;
@@ -1114,7 +1096,6 @@ static irqreturn_t NCR5380_intr(int dumm
 		done = 1;
 		spin_lock_irqsave(instance->host_lock, flags);
 		/* Look for pending interrupts */
-		NCR5380_setup(instance);
 		basr = NCR5380_read(BUS_AND_STATUS_REG);
 		/* XXX dispatch to appropriate routine if found and done=0 */
 		if (basr & BASR_IRQ) {
@@ -1205,7 +1186,6 @@ static irqreturn_t NCR5380_intr(int dumm
  
 static int NCR5380_select(struct Scsi_Host *instance, struct scsi_cmnd *cmd)
 {
-	NCR5380_local_declare();
 	struct NCR5380_hostdata *hostdata = (struct NCR5380_hostdata *) instance->hostdata;
 	unsigned char tmp[3], phase;
 	unsigned char *data;
@@ -1213,7 +1193,6 @@ static int NCR5380_select(struct Scsi_Ho
 	unsigned long timeout;
 	unsigned char value;
 	int err;
-	NCR5380_setup(instance);
 
 	if (hostdata->selecting)
 		goto part2;
@@ -1487,7 +1466,6 @@ failed:
  */
 
 static int NCR5380_transfer_pio(struct Scsi_Host *instance, unsigned char *phase, int *count, unsigned char **data) {
-	NCR5380_local_declare();
 	unsigned char p = *phase, tmp;
 	int c = *count;
 	unsigned char *d = *data;
@@ -1496,7 +1474,6 @@ static int NCR5380_transfer_pio(struct S
 	 */
 	int break_allowed = 0;
 	struct NCR5380_hostdata *hostdata = (struct NCR5380_hostdata *) instance->hostdata;
-	NCR5380_setup(instance);
 
 	if (!(p & SR_IO))
 		dprintk(NDEBUG_PIO, "scsi%d : pio write %d bytes\n", instance->host_no, c);
@@ -1623,10 +1600,8 @@ static int NCR5380_transfer_pio(struct S
  *	Locks: caller holds queue lock
  */
  
-static void do_reset(struct Scsi_Host *host) {
-	NCR5380_local_declare();
-	NCR5380_setup(host);
-
+static void do_reset(struct Scsi_Host *instance)
+{
 	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(25);
@@ -1645,13 +1620,11 @@ static void do_reset(struct Scsi_Host *h
  *	FIXME: sort this out and get new_eh running
  */
 
-static int do_abort(struct Scsi_Host *host) {
-	NCR5380_local_declare();
+static int do_abort(struct Scsi_Host *instance)
+{
 	unsigned char *msgptr, phase, tmp;
 	int len;
 	int rc;
-	NCR5380_setup(host);
-
 
 	/* Request message out phase */
 	NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_ATN);
@@ -1666,7 +1639,7 @@ static int do_abort(struct Scsi_Host *ho
 	 * the target sees, so we just handshake.
 	 */
 
-	rc = NCR5380_poll_politely(host, STATUS_REG, SR_REQ, SR_REQ, 60 * HZ);
+	rc = NCR5380_poll_politely(instance, STATUS_REG, SR_REQ, SR_REQ, 60 * HZ);
 	
 	if(rc < 0)
 		return -1;
@@ -1677,7 +1650,7 @@ static int do_abort(struct Scsi_Host *ho
 
 	if ((tmp & PHASE_MASK) != PHASE_MSGOUT) {
 		NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_ATN | ICR_ASSERT_ACK);
-		rc = NCR5380_poll_politely(host, STATUS_REG, SR_REQ, 0, 3*HZ);
+		rc = NCR5380_poll_politely(instance, STATUS_REG, SR_REQ, 0, 3 * HZ);
 		NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_ATN);
 		if(rc == -1)
 			return -1;
@@ -1686,7 +1659,7 @@ static int do_abort(struct Scsi_Host *ho
 	msgptr = &tmp;
 	len = 1;
 	phase = PHASE_MSGOUT;
-	NCR5380_transfer_pio(host, &phase, &len, &msgptr);
+	NCR5380_transfer_pio(instance, &phase, &len, &msgptr);
 
 	/*
 	 * If we got here, and the command completed successfully,
@@ -1719,7 +1692,6 @@ static int do_abort(struct Scsi_Host *ho
 
 
 static int NCR5380_transfer_dma(struct Scsi_Host *instance, unsigned char *phase, int *count, unsigned char **data) {
-	NCR5380_local_declare();
 	register int c = *count;
 	register unsigned char p = *phase;
 	register unsigned char *d = *data;
@@ -1732,8 +1704,6 @@ static int NCR5380_transfer_dma(struct S
 
 	struct NCR5380_hostdata *hostdata = (struct NCR5380_hostdata *) instance->hostdata;
 
-	NCR5380_setup(instance);
-
 	if ((tmp = (NCR5380_read(STATUS_REG) & PHASE_MASK)) != p) {
 		*phase = tmp;
 		return -1;
@@ -2000,7 +1970,6 @@ static int NCR5380_transfer_dma(struct S
  */
 
 static void NCR5380_information_transfer(struct Scsi_Host *instance) {
-	NCR5380_local_declare();
 	struct NCR5380_hostdata *hostdata = (struct NCR5380_hostdata *)instance->hostdata;
 	unsigned char msgout = NOP;
 	int sink = 0;
@@ -2014,8 +1983,6 @@ static void NCR5380_information_transfer
 	/* RvC: we need to set the end of the polling time */
 	unsigned long poll_time = jiffies + USLEEP_POLL;
 
-	NCR5380_setup(instance);
-
 	while (1) {
 		tmp = NCR5380_read(STATUS_REG);
 		/* We only have a valid SCSI phase when REQ is asserted */
@@ -2406,7 +2373,6 @@ static void NCR5380_information_transfer
  */
 
 static void NCR5380_reselect(struct Scsi_Host *instance) {
-	NCR5380_local_declare();
 	struct NCR5380_hostdata *hostdata = (struct NCR5380_hostdata *)
 	 instance->hostdata;
 	unsigned char target_mask;
@@ -2416,7 +2382,6 @@ static void NCR5380_reselect(struct Scsi
 	unsigned char *data;
 	struct scsi_cmnd *tmp = NULL, *prev;
 	int abort = 0;
-	NCR5380_setup(instance);
 
 	/*
 	 * Disable arbitration, etc. since the host adapter obviously
@@ -2525,10 +2490,8 @@ static void NCR5380_reselect(struct Scsi
 
 #ifdef REAL_DMA
 static void NCR5380_dma_complete(NCR5380_instance * instance) {
-	NCR5380_local_declare();
 	struct NCR5380_hostdata *hostdata = (struct NCR5380_hostdata *) instance->hostdata;
 	int transferred;
-	NCR5380_setup(instance);
 
 	/*
 	 * XXX this might not be right.
@@ -2581,7 +2544,6 @@ static void NCR5380_dma_complete(NCR5380
 
 static int NCR5380_abort(struct scsi_cmnd *cmd)
 {
-	NCR5380_local_declare();
 	struct Scsi_Host *instance = cmd->device->host;
 	struct NCR5380_hostdata *hostdata = (struct NCR5380_hostdata *) instance->hostdata;
 	struct scsi_cmnd *tmp, **prev;
@@ -2590,8 +2552,6 @@ static int NCR5380_abort(struct scsi_cmn
 
 	NCR5380_print_status(instance);
 
-	NCR5380_setup(instance);
-
 	dprintk(NDEBUG_ABORT, "scsi%d : abort called\n", instance->host_no);
 	dprintk(NDEBUG_ABORT, "        basr 0x%X, sr 0x%X\n", NCR5380_read(BUS_AND_STATUS_REG), NCR5380_read(STATUS_REG));
 
@@ -2737,8 +2697,6 @@ static int NCR5380_bus_reset(struct scsi
 {
 	struct Scsi_Host *instance = cmd->device->host;
 
-	NCR5380_local_declare();
-	NCR5380_setup(instance);
 	NCR5380_print_status(instance);
 
 	spin_lock_irq(instance->host_lock);
Index: linux/drivers/scsi/arm/cumana_1.c
===================================================================
--- linux.orig/drivers/scsi/arm/cumana_1.c	2015-11-18 19:25:56.000000000 +1100
+++ linux/drivers/scsi/arm/cumana_1.c	2015-11-18 19:33:05.000000000 +1100
@@ -20,10 +20,8 @@
 #define PSEUDO_DMA
 
 #define priv(host)			((struct NCR5380_hostdata *)(host)->hostdata)
-#define NCR5380_local_declare()		struct Scsi_Host *_instance
-#define NCR5380_setup(instance)		_instance = instance
-#define NCR5380_read(reg)		cumanascsi_read(_instance, reg)
-#define NCR5380_write(reg, value)	cumanascsi_write(_instance, reg, value)
+#define NCR5380_read(reg)		cumanascsi_read(instance, reg)
+#define NCR5380_write(reg, value)	cumanascsi_write(instance, reg, value)
 #define NCR5380_intr			cumanascsi_intr
 #define NCR5380_queue_command		cumanascsi_queue_command
 #define NCR5380_info			cumanascsi_info
Index: linux/drivers/scsi/arm/oak.c
===================================================================
--- linux.orig/drivers/scsi/arm/oak.c	2015-11-18 19:25:56.000000000 +1100
+++ linux/drivers/scsi/arm/oak.c	2015-11-18 19:33:05.000000000 +1100
@@ -20,11 +20,12 @@
 #define DONT_USE_INTR
 
 #define priv(host)			((struct NCR5380_hostdata *)(host)->hostdata)
-#define NCR5380_local_declare()		void __iomem *_base
-#define NCR5380_setup(host)		_base = priv(host)->base
 
-#define NCR5380_read(reg)		readb(_base + ((reg) << 2))
-#define NCR5380_write(reg, value)	writeb(value, _base + ((reg) << 2))
+#define NCR5380_read(reg) \
+	readb(priv(instance)->base + ((reg) << 2))
+#define NCR5380_write(reg, value) \
+	writeb(value, priv(instance)->base + ((reg) << 2))
+
 #define NCR5380_queue_command		oakscsi_queue_command
 #define NCR5380_info			oakscsi_info
 #define NCR5380_show_info		oakscsi_show_info
Index: linux/drivers/scsi/dmx3191d.c
===================================================================
--- linux.orig/drivers/scsi/dmx3191d.c	2015-11-18 19:25:56.000000000 +1100
+++ linux/drivers/scsi/dmx3191d.c	2015-11-18 19:33:05.000000000 +1100
@@ -36,12 +36,10 @@
 
 #define DONT_USE_INTR
 
-#define NCR5380_read(reg)		inb(port + reg)
-#define NCR5380_write(reg, value)	outb(value, port + reg)
+#define NCR5380_read(reg)		inb(instance->io_port + reg)
+#define NCR5380_write(reg, value)	outb(value, instance->io_port + reg)
 
 #define NCR5380_implementation_fields	/* none */
-#define NCR5380_local_declare()		unsigned int port
-#define NCR5380_setup(instance)		port = instance->io_port
 
 /*
  * Includes needed for NCR5380.[ch] (XXX: Move them to NCR5380.h)
Index: linux/drivers/scsi/dtc.c
===================================================================
--- linux.orig/drivers/scsi/dtc.c	2015-11-18 19:33:02.000000000 +1100
+++ linux/drivers/scsi/dtc.c	2015-11-18 19:33:05.000000000 +1100
@@ -325,8 +325,6 @@ static inline int NCR5380_pread(struct S
 	unsigned char *d = dst;
 	int i;			/* For counting time spent in the poll-loop */
 	struct NCR5380_hostdata *hostdata = shost_priv(instance);
-	NCR5380_local_declare();
-	NCR5380_setup(instance);
 
 	i = 0;
 	NCR5380_read(RESET_PARITY_INTERRUPT_REG);
@@ -342,7 +340,7 @@ static inline int NCR5380_pread(struct S
 		while (NCR5380_read(DTC_CONTROL_REG) & CSR_HOST_BUF_NOT_RDY)
 			++i;
 		rtrc(3);
-		memcpy_fromio(d, base + DTC_DATA_BUF, 128);
+		memcpy_fromio(d, hostdata->base + DTC_DATA_BUF, 128);
 		d += 128;
 		len -= 128;
 		rtrc(7);
@@ -377,8 +375,6 @@ static inline int NCR5380_pwrite(struct
 {
 	int i;
 	struct NCR5380_hostdata *hostdata = shost_priv(instance);
-	NCR5380_local_declare();
-	NCR5380_setup(instance);
 
 	NCR5380_read(RESET_PARITY_INTERRUPT_REG);
 	NCR5380_write(MODE_REG, MR_ENABLE_EOP_INTR | MR_DMA_MODE);
@@ -394,7 +390,7 @@ static inline int NCR5380_pwrite(struct
 		while (NCR5380_read(DTC_CONTROL_REG) & CSR_HOST_BUF_NOT_RDY)
 			++i;
 		rtrc(3);
-		memcpy_toio(base + DTC_DATA_BUF, src, 128);
+		memcpy_toio(hostdata->base + DTC_DATA_BUF, src, 128);
 		src += 128;
 		len -= 128;
 	}
@@ -420,15 +416,15 @@ MODULE_LICENSE("GPL");
 
 static int dtc_release(struct Scsi_Host *shost)
 {
-	NCR5380_local_declare();
-	NCR5380_setup(shost);
+	struct NCR5380_hostdata *hostdata = shost_priv(shost);
+
 	if (shost->irq != NO_IRQ)
 		free_irq(shost->irq, shost);
 	NCR5380_exit(shost);
 	if (shost->io_port && shost->n_io_port)
 		release_region(shost->io_port, shost->n_io_port);
 	scsi_unregister(shost);
-	iounmap(base);
+	iounmap(hostdata->base);
 	return 0;
 }
 
Index: linux/drivers/scsi/dtc.h
===================================================================
--- linux.orig/drivers/scsi/dtc.h	2015-11-18 19:33:02.000000000 +1100
+++ linux/drivers/scsi/dtc.h	2015-11-18 19:33:05.000000000 +1100
@@ -21,13 +21,8 @@
 #define NCR5380_implementation_fields \
     void __iomem *base
 
-#define NCR5380_local_declare() \
-    void __iomem *base
-
-#define NCR5380_setup(instance) \
-    base = ((struct NCR5380_hostdata *)(instance)->hostdata)->base
-
-#define DTC_address(reg) (base + DTC_5380_OFFSET + reg)
+#define DTC_address(reg) \
+	(((struct NCR5380_hostdata *)shost_priv(instance))->base + DTC_5380_OFFSET + reg)
 
 #define NCR5380_read(reg) (readb(DTC_address(reg)))
 #define NCR5380_write(reg, value) (writeb(value, DTC_address(reg)))
Index: linux/drivers/scsi/g_NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/g_NCR5380.c	2015-11-18 19:33:04.000000000 +1100
+++ linux/drivers/scsi/g_NCR5380.c	2015-11-18 19:33:05.000000000 +1100
@@ -459,9 +459,6 @@ static int __init generic_NCR5380_detect
  
 static int generic_NCR5380_release_resources(struct Scsi_Host *instance)
 {
-	NCR5380_local_declare();
-	NCR5380_setup(instance);
-	
 	if (instance->irq != NO_IRQ)
 		free_irq(instance->irq, instance);
 	NCR5380_exit(instance);
@@ -520,13 +517,13 @@ generic_NCR5380_biosparam(struct scsi_de
  
 static inline int NCR5380_pread(struct Scsi_Host *instance, unsigned char *dst, int len)
 {
+#ifdef SCSI_G_NCR5380_MEM
+	struct NCR5380_hostdata *hostdata = shost_priv(instance);
+#endif
 	int blocks = len / 128;
 	int start = 0;
 	int bl;
 
-	NCR5380_local_declare();
-	NCR5380_setup(instance);
-
 	NCR5380_write(C400_CONTROL_STATUS_REG, CSR_BASE | CSR_TRANS_DIR);
 	NCR5380_write(C400_BLOCK_COUNTER_REG, blocks);
 	while (1) {
@@ -547,7 +544,8 @@ static inline int NCR5380_pread(struct S
 		}
 #else
 		/* implies SCSI_G_NCR5380_MEM */
-		memcpy_fromio(dst + start, iomem + NCR53C400_host_buffer, 128);
+		memcpy_fromio(dst + start,
+		              hostdata->iomem + NCR53C400_host_buffer, 128);
 #endif
 		start += 128;
 		blocks--;
@@ -567,7 +565,8 @@ static inline int NCR5380_pread(struct S
 		}
 #else
 		/* implies SCSI_G_NCR5380_MEM */
-		memcpy_fromio(dst + start, iomem + NCR53C400_host_buffer, 128);
+		memcpy_fromio(dst + start,
+		              hostdata->iomem + NCR53C400_host_buffer, 128);
 #endif
 		start += 128;
 		blocks--;
@@ -604,14 +603,14 @@ static inline int NCR5380_pread(struct S
 
 static inline int NCR5380_pwrite(struct Scsi_Host *instance, unsigned char *src, int len)
 {
+#ifdef SCSI_G_NCR5380_MEM
+	struct NCR5380_hostdata *hostdata = shost_priv(instance);
+#endif
 	int blocks = len / 128;
 	int start = 0;
 	int bl;
 	int i;
 
-	NCR5380_local_declare();
-	NCR5380_setup(instance);
-
 	NCR5380_write(C400_CONTROL_STATUS_REG, CSR_BASE);
 	NCR5380_write(C400_BLOCK_COUNTER_REG, blocks);
 	while (1) {
@@ -632,7 +631,8 @@ static inline int NCR5380_pwrite(struct
 		}
 #else
 		/* implies SCSI_G_NCR5380_MEM */
-		memcpy_toio(iomem + NCR53C400_host_buffer, src + start, 128);
+		memcpy_toio(hostdata->iomem + NCR53C400_host_buffer,
+		            src + start, 128);
 #endif
 		start += 128;
 		blocks--;
@@ -648,7 +648,8 @@ static inline int NCR5380_pwrite(struct
 		}
 #else
 		/* implies SCSI_G_NCR5380_MEM */
-		memcpy_toio(iomem + NCR53C400_host_buffer, src + start, 128);
+		memcpy_toio(hostdata->iomem + NCR53C400_host_buffer,
+		            src + start, 128);
 #endif
 		start += 128;
 		blocks--;
Index: linux/drivers/scsi/g_NCR5380.h
===================================================================
--- linux.orig/drivers/scsi/g_NCR5380.h	2015-11-18 19:33:04.000000000 +1100
+++ linux/drivers/scsi/g_NCR5380.h	2015-11-18 19:33:05.000000000 +1100
@@ -46,17 +46,12 @@
 #define NCR5380_region_size 8
 #endif
 
-#define NCR5380_read(reg) (inb(NCR5380_map_name + (reg)))
-#define NCR5380_write(reg, value) (outb((value), (NCR5380_map_name + (reg))))
+#define NCR5380_read(reg) \
+	inb(instance->io_port + (reg))
+#define NCR5380_write(reg, value) \
+	outb(value, instance->io_port + (reg))
 
-#define NCR5380_implementation_fields \
-    NCR5380_map_type NCR5380_map_name
-
-#define NCR5380_local_declare() \
-    register NCR5380_implementation_fields
-
-#define NCR5380_setup(instance) \
-    NCR5380_map_name = (NCR5380_map_type)((instance)->NCR5380_instance_name)
+#define NCR5380_implementation_fields /* none */
 
 #else 
 /* therefore SCSI_G_NCR5380_MEM */
@@ -70,19 +65,16 @@
 #define NCR53C400_host_buffer 0x3900
 #define NCR5380_region_size 0x3a00
 
-#define NCR5380_read(reg) readb(iomem + NCR53C400_mem_base + (reg))
-#define NCR5380_write(reg, value) writeb(value, iomem + NCR53C400_mem_base + (reg))
+#define NCR5380_read(reg) \
+	readb(((struct NCR5380_hostdata *)shost_priv(instance))->iomem + \
+	      NCR53C400_mem_base + (reg))
+#define NCR5380_write(reg, value) \
+	writeb(value, ((struct NCR5380_hostdata *)shost_priv(instance))->iomem + \
+	       NCR53C400_mem_base + (reg))
 
 #define NCR5380_implementation_fields \
-    NCR5380_map_type NCR5380_map_name; \
     void __iomem *iomem;
 
-#define NCR5380_local_declare() \
-    register void __iomem *iomem
-
-#define NCR5380_setup(instance) \
-    iomem = (((struct NCR5380_hostdata *)(instance)->hostdata)->iomem)
-
 #endif
 
 #define NCR5380_intr generic_NCR5380_intr
Index: linux/drivers/scsi/mac_scsi.c
===================================================================
--- linux.orig/drivers/scsi/mac_scsi.c	2015-11-18 19:25:56.000000000 +1100
+++ linux/drivers/scsi/mac_scsi.c	2015-11-18 19:33:05.000000000 +1100
@@ -32,11 +32,9 @@
 #define PSEUDO_DMA
 
 #define NCR5380_implementation_fields   unsigned char *pdma_base
-#define NCR5380_local_declare()         struct Scsi_Host *_instance
-#define NCR5380_setup(instance)         _instance = instance
 
-#define NCR5380_read(reg)               macscsi_read(_instance, reg)
-#define NCR5380_write(reg, value)       macscsi_write(_instance, reg, value)
+#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
@@ -129,9 +127,6 @@ static void mac_scsi_reset_boot(struct S
 {
 	unsigned long end;
 
-	NCR5380_local_declare();
-	NCR5380_setup(instance);
-	
 	/*
 	 * Do a SCSI reset to clean up the bus during initialization. No messing
 	 * with the queues, interrupts, or locks necessary here.
@@ -235,9 +230,6 @@ static int macscsi_pread(struct Scsi_Hos
 	unsigned char *d;
 	unsigned char *s;
 
-	NCR5380_local_declare();
-	NCR5380_setup(instance);
-
 	s = hostdata->pdma_base + (INPUT_DATA_REG << 4);
 	d = dst;
 
@@ -329,9 +321,6 @@ static int macscsi_pwrite(struct Scsi_Ho
 	unsigned char *s;
 	unsigned char *d;
 
-	NCR5380_local_declare();
-	NCR5380_setup(instance);
-
 	s = src;
 	d = hostdata->pdma_base + (OUTPUT_DATA_REG << 4);
 
Index: linux/drivers/scsi/pas16.h
===================================================================
--- linux.orig/drivers/scsi/pas16.h	2015-11-18 19:33:04.000000000 +1100
+++ linux/drivers/scsi/pas16.h	2015-11-18 19:33:05.000000000 +1100
@@ -103,16 +103,9 @@
 #define CAN_QUEUE 32 
 #endif
 
-#define NCR5380_implementation_fields \
-    volatile unsigned short io_port
+#define NCR5380_implementation_fields /* none */
 
-#define NCR5380_local_declare() \
-    volatile unsigned short io_port
-
-#define NCR5380_setup(instance) \
-    io_port = (instance)->io_port
-
-#define PAS16_io_port(reg) ( io_port + pas16_offset[(reg)] )
+#define PAS16_io_port(reg) (instance->io_port + pas16_offset[(reg)])
 
 #define NCR5380_read(reg) ( inb(PAS16_io_port(reg)) )
 #define NCR5380_write(reg, value) ( outb((value),PAS16_io_port(reg)) )
Index: linux/drivers/scsi/t128.c
===================================================================
--- linux.orig/drivers/scsi/t128.c	2015-11-18 19:33:02.000000000 +1100
+++ linux/drivers/scsi/t128.c	2015-11-18 19:33:05.000000000 +1100
@@ -248,15 +248,15 @@ found:
 
 static int t128_release(struct Scsi_Host *shost)
 {
-	NCR5380_local_declare();
-	NCR5380_setup(shost);
+	struct NCR5380_hostdata *hostdata = shost_priv(shost);
+
 	if (shost->irq != NO_IRQ)
 		free_irq(shost->irq, shost);
 	NCR5380_exit(shost);
 	if (shost->io_port && shost->n_io_port)
 		release_region(shost->io_port, shost->n_io_port);
 	scsi_unregister(shost);
-	iounmap(base);
+	iounmap(hostdata->base);
 	return 0;
 }
 
@@ -302,14 +302,14 @@ static int t128_biosparam(struct scsi_de
  * 	timeout.
  */
 
-static inline int NCR5380_pread (struct Scsi_Host *instance, unsigned char *dst,
-    int len) {
-    NCR5380_local_declare();
-    void __iomem *reg;
+static inline int
+NCR5380_pread(struct Scsi_Host *instance, unsigned char *dst, int len)
+{
+	struct NCR5380_hostdata *hostdata = shost_priv(instance);
+	void __iomem *reg, *base = hostdata->base;
     unsigned char *d = dst;
     register int i = len;
 
-    NCR5380_setup(instance);
     reg = base + T_DATA_REG_OFFSET;
 
 #if 0
@@ -348,14 +348,14 @@ static inline int NCR5380_pread (struct
  * 	timeout.
  */
 
-static inline int NCR5380_pwrite (struct Scsi_Host *instance, unsigned char *src,
-    int len) {
-    NCR5380_local_declare();
-    void __iomem *reg;
+static inline int
+NCR5380_pwrite(struct Scsi_Host *instance, unsigned char *src, int len)
+{
+	struct NCR5380_hostdata *hostdata = shost_priv(instance);
+	void __iomem *reg, *base = hostdata->base;
     unsigned char *s = src;
     register int i = len;
 
-    NCR5380_setup(instance);
     reg = base + T_DATA_REG_OFFSET;
 
 #if 0
Index: linux/drivers/scsi/t128.h
===================================================================
--- linux.orig/drivers/scsi/t128.h	2015-11-18 19:33:04.000000000 +1100
+++ linux/drivers/scsi/t128.h	2015-11-18 19:33:05.000000000 +1100
@@ -78,13 +78,8 @@
 #define NCR5380_implementation_fields \
     void __iomem *base
 
-#define NCR5380_local_declare() \
-    void __iomem *base
-
-#define NCR5380_setup(instance) \
-    base = ((struct NCR5380_hostdata *)(instance->hostdata))->base
-
-#define T128_address(reg) (base + T_5380_OFFSET + ((reg) * 0x20))
+#define T128_address(reg) \
+	(((struct NCR5380_hostdata *)shost_priv(instance))->base + T_5380_OFFSET + ((reg) * 0x20))
 
 #define NCR5380_read(reg) readb(T128_address(reg))
 #define NCR5380_write(reg, value) writeb((value),(T128_address(reg)))
Index: linux/drivers/scsi/pas16.c
===================================================================
--- linux.orig/drivers/scsi/pas16.c	2015-11-18 19:33:04.000000000 +1100
+++ linux/drivers/scsi/pas16.c	2015-11-18 19:33:05.000000000 +1100
@@ -188,7 +188,7 @@ static void __init
 	outb( 0x01, io_port + P_TIMEOUT_STATUS_REG_OFFSET );   /* Reset TC */
 	outb( 0x01, io_port + WAIT_STATE );   /* 1 Wait state */
 
-	NCR5380_read( RESET_PARITY_INTERRUPT_REG );
+	inb(io_port + pas16_offset[RESET_PARITY_INTERRUPT_REG]);
 
 	/* Set the SCSI interrupt pointer without mucking up the sound
 	 * interrupt pointer in the same byte.
@@ -263,13 +263,13 @@ static int __init
      * put in an additional test to try to weed them out.
      */
 
-    outb( 0x01, io_port + WAIT_STATE ); 	/* 1 Wait state */
-    NCR5380_write( MODE_REG, 0x20 );		/* Is it really SCSI? */
-    if( NCR5380_read( MODE_REG ) != 0x20 )	/* Write to a reg.    */
-	return 0;				/* and try to read    */
-    NCR5380_write( MODE_REG, 0x00 );		/* it back.	      */
-    if( NCR5380_read( MODE_REG ) != 0x00 )
-	return 0;
+	outb(0x01, io_port + WAIT_STATE);             /* 1 Wait state */
+	outb(0x20, io_port + pas16_offset[MODE_REG]); /* Is it really SCSI? */
+	if (inb(io_port + pas16_offset[MODE_REG]) != 0x20) /* Write to a reg. */
+		return 0;                                  /* and try to read */
+	outb(0x00, io_port + pas16_offset[MODE_REG]);      /* it back. */
+	if (inb(io_port + pas16_offset[MODE_REG]) != 0x00)
+		return 0;
 
     return 1;
 }



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

* [PATCH 05/71] ncr5380: Remove NCR5380_local_declare and NCR5380_setup macros
@ 2015-11-18  8:35   ` Finn Thain
  0 siblings, 0 replies; 268+ messages in thread
From: Finn Thain @ 2015-11-18  8:35 UTC (permalink / raw)
  To: James E.J. Bottomley, Michael Schmitz, linux-m68k, linux-scsi,
	linux-kernel, Russell King, linux-arm-kernel

[-- Attachment #1: ncr5380-eliminate-local_declare-macros --]
[-- Type: text/plain, Size: 28565 bytes --]

The NCR5380_local_declare and NCR5380_setup macros exist to define and
initialize a particular local variable, to provide the address of the
chip registers needed for the driver's implementation of its
NCR5380_read/write register access macros.

In cumana_1 and macscsi, these macros generate pointless code like this,
	struct Scsi_Host *_instance;
	_instance = instance;

In pas16, the use of NCR5380_read/write in pas16_hw_detect() requires that
the io_port local variable has been defined and initialized, but the
NCR5380_local_declare and NCR5380_setup macros can't be used for that
purpose because the Scsi_Host struct has not yet been instantiated.

Moreover, these macros were removed from atari_NCR5380.c long ago and
now they constitute yet another discrepancy between the two core driver
forks.

Remove these "optimizations".

Signed-off-by: Finn Thain <fthain@telegraphics.com.au>

---

Any performance penalty is highly unlikely given the algorithms involved
and the improvements made to compilers over the last two decades. (And
I'd probably accept some loss anyway given the maintainability benefit.)

Following the example of atari_NCR5380.c, the Scsi_Host pointer is now
always named "instance", and the NCR5380_read/write macros depend on this.
I think it is poor style to hard-code the identifier "instance" in these
macros but it is actually an improvement -- previously each NCR5380 driver
named a different local variable in its macro definitions.

Eventually, the NCR5380_read/write macros may have to become function
calls if this is to become a platform driver or a library. The instance
pointer or hostdata pointer will then have to be passed as an argument.

This patch is a step in that direction, in that it rewrites the
NCR5380_read/write macros in terms of hostdata and removes the
NCR5380_read/write usage from pas16_hw_detect() where there is no
Scsi_Host instance as yet.

---
 drivers/scsi/NCR5380.c      |   60 ++++++--------------------------------------
 drivers/scsi/arm/cumana_1.c |    6 +---
 drivers/scsi/arm/oak.c      |    9 +++---
 drivers/scsi/dmx3191d.c     |    6 +---
 drivers/scsi/dtc.c          |   14 +++-------
 drivers/scsi/dtc.h          |    9 +-----
 drivers/scsi/g_NCR5380.c    |   27 ++++++++++---------
 drivers/scsi/g_NCR5380.h    |   30 ++++++++--------------
 drivers/scsi/mac_scsi.c     |   15 +----------
 drivers/scsi/pas16.c        |   16 +++++------
 drivers/scsi/pas16.h        |   11 +-------
 drivers/scsi/t128.c         |   26 +++++++++----------
 drivers/scsi/t128.h         |    9 +-----
 13 files changed, 77 insertions(+), 161 deletions(-)

Index: linux/drivers/scsi/NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/NCR5380.c	2015-11-18 19:32:59.000000000 +1100
+++ linux/drivers/scsi/NCR5380.c	2015-11-18 19:33:05.000000000 +1100
@@ -230,11 +230,6 @@
  * USLEEP_POLL - amount of time, in jiffies, to poll
  *
  * These macros MUST be defined :
- * NCR5380_local_declare() - declare any local variables needed for your
- *      transfer routines.
- *
- * NCR5380_setup(instance) - initialize any local variables needed from a given
- *      instance of the host adapter for NCR5380_{read,write,pread,pwrite}
  * 
  * NCR5380_read(register)  - read from the specified register
  *
@@ -267,8 +262,8 @@
  * possible) function may be used.
  */
 
-static int do_abort(struct Scsi_Host *host);
-static void do_reset(struct Scsi_Host *host);
+static int do_abort(struct Scsi_Host *);
+static void do_reset(struct Scsi_Host *);
 
 /*
  *	initialize_SCp		-	init the scsi pointer field
@@ -313,12 +308,9 @@ static inline void initialize_SCp(struct
  
 static int NCR5380_poll_politely(struct Scsi_Host *instance, int reg, int bit, int val, int t)
 {
-	NCR5380_local_declare();
 	int n = 500;		/* At about 8uS a cycle for the cpu access */
 	unsigned long end = jiffies + t;
 	int r;
-	
-	NCR5380_setup(instance);
 
 	while( n-- > 0)
 	{
@@ -406,9 +398,7 @@ mrs[] = {
 
 static void NCR5380_print(struct Scsi_Host *instance)
 {
-	NCR5380_local_declare();
 	unsigned char status, data, basr, mr, icr, i;
-	NCR5380_setup(instance);
 
 	data = NCR5380_read(CURRENT_SCSI_DATA_REG);
 	status = NCR5380_read(STATUS_REG);
@@ -447,10 +437,8 @@ static void NCR5380_print(struct Scsi_Ho
 
 static void NCR5380_print_phase(struct Scsi_Host *instance)
 {
-	NCR5380_local_declare();
 	unsigned char status;
 	int i;
-	NCR5380_setup(instance);
 
 	status = NCR5380_read(STATUS_REG);
 	if (!(status & SR_REQ))
@@ -566,11 +554,9 @@ static irqreturn_t __init probe_intr(int
 static int __init __maybe_unused NCR5380_probe_irq(struct Scsi_Host *instance,
 						int possible)
 {
-	NCR5380_local_declare();
 	struct NCR5380_hostdata *hostdata = (struct NCR5380_hostdata *) instance->hostdata;
 	unsigned long timeout;
 	int trying_irqs, i, mask;
-	NCR5380_setup(instance);
 
 	for (trying_irqs = 0, i = 1, mask = 2; i < 16; ++i, mask <<= 1)
 		if ((mask & possible) && (request_irq(i, &probe_intr, 0, "NCR-probe", NULL) == 0))
@@ -791,7 +777,6 @@ static void lprint_opcode(int opcode, st
 
 static int NCR5380_init(struct Scsi_Host *instance, int flags)
 {
-	NCR5380_local_declare();
 	int i, pass;
 	unsigned long timeout;
 	struct NCR5380_hostdata *hostdata = (struct NCR5380_hostdata *) instance->hostdata;
@@ -808,8 +793,6 @@ static int NCR5380_init(struct Scsi_Host
 		instance->NCR5380_instance_name += NCR53C400_address_adjust;
 #endif
 
-	NCR5380_setup(instance);
-
 	hostdata->aborted = 0;
 	hostdata->id_mask = 1 << instance->this_id;
 	for (i = hostdata->id_mask; i <= 0x80; i <<= 1)
@@ -1100,7 +1083,6 @@ static void NCR5380_main(struct work_str
 
 static irqreturn_t NCR5380_intr(int dummy, void *dev_id)
 {
-	NCR5380_local_declare();
 	struct Scsi_Host *instance = dev_id;
 	struct NCR5380_hostdata *hostdata = (struct NCR5380_hostdata *) instance->hostdata;
 	int done;
@@ -1114,7 +1096,6 @@ static irqreturn_t NCR5380_intr(int dumm
 		done = 1;
 		spin_lock_irqsave(instance->host_lock, flags);
 		/* Look for pending interrupts */
-		NCR5380_setup(instance);
 		basr = NCR5380_read(BUS_AND_STATUS_REG);
 		/* XXX dispatch to appropriate routine if found and done=0 */
 		if (basr & BASR_IRQ) {
@@ -1205,7 +1186,6 @@ static irqreturn_t NCR5380_intr(int dumm
  
 static int NCR5380_select(struct Scsi_Host *instance, struct scsi_cmnd *cmd)
 {
-	NCR5380_local_declare();
 	struct NCR5380_hostdata *hostdata = (struct NCR5380_hostdata *) instance->hostdata;
 	unsigned char tmp[3], phase;
 	unsigned char *data;
@@ -1213,7 +1193,6 @@ static int NCR5380_select(struct Scsi_Ho
 	unsigned long timeout;
 	unsigned char value;
 	int err;
-	NCR5380_setup(instance);
 
 	if (hostdata->selecting)
 		goto part2;
@@ -1487,7 +1466,6 @@ failed:
  */
 
 static int NCR5380_transfer_pio(struct Scsi_Host *instance, unsigned char *phase, int *count, unsigned char **data) {
-	NCR5380_local_declare();
 	unsigned char p = *phase, tmp;
 	int c = *count;
 	unsigned char *d = *data;
@@ -1496,7 +1474,6 @@ static int NCR5380_transfer_pio(struct S
 	 */
 	int break_allowed = 0;
 	struct NCR5380_hostdata *hostdata = (struct NCR5380_hostdata *) instance->hostdata;
-	NCR5380_setup(instance);
 
 	if (!(p & SR_IO))
 		dprintk(NDEBUG_PIO, "scsi%d : pio write %d bytes\n", instance->host_no, c);
@@ -1623,10 +1600,8 @@ static int NCR5380_transfer_pio(struct S
  *	Locks: caller holds queue lock
  */
  
-static void do_reset(struct Scsi_Host *host) {
-	NCR5380_local_declare();
-	NCR5380_setup(host);
-
+static void do_reset(struct Scsi_Host *instance)
+{
 	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(25);
@@ -1645,13 +1620,11 @@ static void do_reset(struct Scsi_Host *h
  *	FIXME: sort this out and get new_eh running
  */
 
-static int do_abort(struct Scsi_Host *host) {
-	NCR5380_local_declare();
+static int do_abort(struct Scsi_Host *instance)
+{
 	unsigned char *msgptr, phase, tmp;
 	int len;
 	int rc;
-	NCR5380_setup(host);
-
 
 	/* Request message out phase */
 	NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_ATN);
@@ -1666,7 +1639,7 @@ static int do_abort(struct Scsi_Host *ho
 	 * the target sees, so we just handshake.
 	 */
 
-	rc = NCR5380_poll_politely(host, STATUS_REG, SR_REQ, SR_REQ, 60 * HZ);
+	rc = NCR5380_poll_politely(instance, STATUS_REG, SR_REQ, SR_REQ, 60 * HZ);
 	
 	if(rc < 0)
 		return -1;
@@ -1677,7 +1650,7 @@ static int do_abort(struct Scsi_Host *ho
 
 	if ((tmp & PHASE_MASK) != PHASE_MSGOUT) {
 		NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_ATN | ICR_ASSERT_ACK);
-		rc = NCR5380_poll_politely(host, STATUS_REG, SR_REQ, 0, 3*HZ);
+		rc = NCR5380_poll_politely(instance, STATUS_REG, SR_REQ, 0, 3 * HZ);
 		NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_ATN);
 		if(rc == -1)
 			return -1;
@@ -1686,7 +1659,7 @@ static int do_abort(struct Scsi_Host *ho
 	msgptr = &tmp;
 	len = 1;
 	phase = PHASE_MSGOUT;
-	NCR5380_transfer_pio(host, &phase, &len, &msgptr);
+	NCR5380_transfer_pio(instance, &phase, &len, &msgptr);
 
 	/*
 	 * If we got here, and the command completed successfully,
@@ -1719,7 +1692,6 @@ static int do_abort(struct Scsi_Host *ho
 
 
 static int NCR5380_transfer_dma(struct Scsi_Host *instance, unsigned char *phase, int *count, unsigned char **data) {
-	NCR5380_local_declare();
 	register int c = *count;
 	register unsigned char p = *phase;
 	register unsigned char *d = *data;
@@ -1732,8 +1704,6 @@ static int NCR5380_transfer_dma(struct S
 
 	struct NCR5380_hostdata *hostdata = (struct NCR5380_hostdata *) instance->hostdata;
 
-	NCR5380_setup(instance);
-
 	if ((tmp = (NCR5380_read(STATUS_REG) & PHASE_MASK)) != p) {
 		*phase = tmp;
 		return -1;
@@ -2000,7 +1970,6 @@ static int NCR5380_transfer_dma(struct S
  */
 
 static void NCR5380_information_transfer(struct Scsi_Host *instance) {
-	NCR5380_local_declare();
 	struct NCR5380_hostdata *hostdata = (struct NCR5380_hostdata *)instance->hostdata;
 	unsigned char msgout = NOP;
 	int sink = 0;
@@ -2014,8 +1983,6 @@ static void NCR5380_information_transfer
 	/* RvC: we need to set the end of the polling time */
 	unsigned long poll_time = jiffies + USLEEP_POLL;
 
-	NCR5380_setup(instance);
-
 	while (1) {
 		tmp = NCR5380_read(STATUS_REG);
 		/* We only have a valid SCSI phase when REQ is asserted */
@@ -2406,7 +2373,6 @@ static void NCR5380_information_transfer
  */
 
 static void NCR5380_reselect(struct Scsi_Host *instance) {
-	NCR5380_local_declare();
 	struct NCR5380_hostdata *hostdata = (struct NCR5380_hostdata *)
 	 instance->hostdata;
 	unsigned char target_mask;
@@ -2416,7 +2382,6 @@ static void NCR5380_reselect(struct Scsi
 	unsigned char *data;
 	struct scsi_cmnd *tmp = NULL, *prev;
 	int abort = 0;
-	NCR5380_setup(instance);
 
 	/*
 	 * Disable arbitration, etc. since the host adapter obviously
@@ -2525,10 +2490,8 @@ static void NCR5380_reselect(struct Scsi
 
 #ifdef REAL_DMA
 static void NCR5380_dma_complete(NCR5380_instance * instance) {
-	NCR5380_local_declare();
 	struct NCR5380_hostdata *hostdata = (struct NCR5380_hostdata *) instance->hostdata;
 	int transferred;
-	NCR5380_setup(instance);
 
 	/*
 	 * XXX this might not be right.
@@ -2581,7 +2544,6 @@ static void NCR5380_dma_complete(NCR5380
 
 static int NCR5380_abort(struct scsi_cmnd *cmd)
 {
-	NCR5380_local_declare();
 	struct Scsi_Host *instance = cmd->device->host;
 	struct NCR5380_hostdata *hostdata = (struct NCR5380_hostdata *) instance->hostdata;
 	struct scsi_cmnd *tmp, **prev;
@@ -2590,8 +2552,6 @@ static int NCR5380_abort(struct scsi_cmn
 
 	NCR5380_print_status(instance);
 
-	NCR5380_setup(instance);
-
 	dprintk(NDEBUG_ABORT, "scsi%d : abort called\n", instance->host_no);
 	dprintk(NDEBUG_ABORT, "        basr 0x%X, sr 0x%X\n", NCR5380_read(BUS_AND_STATUS_REG), NCR5380_read(STATUS_REG));
 
@@ -2737,8 +2697,6 @@ static int NCR5380_bus_reset(struct scsi
 {
 	struct Scsi_Host *instance = cmd->device->host;
 
-	NCR5380_local_declare();
-	NCR5380_setup(instance);
 	NCR5380_print_status(instance);
 
 	spin_lock_irq(instance->host_lock);
Index: linux/drivers/scsi/arm/cumana_1.c
===================================================================
--- linux.orig/drivers/scsi/arm/cumana_1.c	2015-11-18 19:25:56.000000000 +1100
+++ linux/drivers/scsi/arm/cumana_1.c	2015-11-18 19:33:05.000000000 +1100
@@ -20,10 +20,8 @@
 #define PSEUDO_DMA
 
 #define priv(host)			((struct NCR5380_hostdata *)(host)->hostdata)
-#define NCR5380_local_declare()		struct Scsi_Host *_instance
-#define NCR5380_setup(instance)		_instance = instance
-#define NCR5380_read(reg)		cumanascsi_read(_instance, reg)
-#define NCR5380_write(reg, value)	cumanascsi_write(_instance, reg, value)
+#define NCR5380_read(reg)		cumanascsi_read(instance, reg)
+#define NCR5380_write(reg, value)	cumanascsi_write(instance, reg, value)
 #define NCR5380_intr			cumanascsi_intr
 #define NCR5380_queue_command		cumanascsi_queue_command
 #define NCR5380_info			cumanascsi_info
Index: linux/drivers/scsi/arm/oak.c
===================================================================
--- linux.orig/drivers/scsi/arm/oak.c	2015-11-18 19:25:56.000000000 +1100
+++ linux/drivers/scsi/arm/oak.c	2015-11-18 19:33:05.000000000 +1100
@@ -20,11 +20,12 @@
 #define DONT_USE_INTR
 
 #define priv(host)			((struct NCR5380_hostdata *)(host)->hostdata)
-#define NCR5380_local_declare()		void __iomem *_base
-#define NCR5380_setup(host)		_base = priv(host)->base
 
-#define NCR5380_read(reg)		readb(_base + ((reg) << 2))
-#define NCR5380_write(reg, value)	writeb(value, _base + ((reg) << 2))
+#define NCR5380_read(reg) \
+	readb(priv(instance)->base + ((reg) << 2))
+#define NCR5380_write(reg, value) \
+	writeb(value, priv(instance)->base + ((reg) << 2))
+
 #define NCR5380_queue_command		oakscsi_queue_command
 #define NCR5380_info			oakscsi_info
 #define NCR5380_show_info		oakscsi_show_info
Index: linux/drivers/scsi/dmx3191d.c
===================================================================
--- linux.orig/drivers/scsi/dmx3191d.c	2015-11-18 19:25:56.000000000 +1100
+++ linux/drivers/scsi/dmx3191d.c	2015-11-18 19:33:05.000000000 +1100
@@ -36,12 +36,10 @@
 
 #define DONT_USE_INTR
 
-#define NCR5380_read(reg)		inb(port + reg)
-#define NCR5380_write(reg, value)	outb(value, port + reg)
+#define NCR5380_read(reg)		inb(instance->io_port + reg)
+#define NCR5380_write(reg, value)	outb(value, instance->io_port + reg)
 
 #define NCR5380_implementation_fields	/* none */
-#define NCR5380_local_declare()		unsigned int port
-#define NCR5380_setup(instance)		port = instance->io_port
 
 /*
  * Includes needed for NCR5380.[ch] (XXX: Move them to NCR5380.h)
Index: linux/drivers/scsi/dtc.c
===================================================================
--- linux.orig/drivers/scsi/dtc.c	2015-11-18 19:33:02.000000000 +1100
+++ linux/drivers/scsi/dtc.c	2015-11-18 19:33:05.000000000 +1100
@@ -325,8 +325,6 @@ static inline int NCR5380_pread(struct S
 	unsigned char *d = dst;
 	int i;			/* For counting time spent in the poll-loop */
 	struct NCR5380_hostdata *hostdata = shost_priv(instance);
-	NCR5380_local_declare();
-	NCR5380_setup(instance);
 
 	i = 0;
 	NCR5380_read(RESET_PARITY_INTERRUPT_REG);
@@ -342,7 +340,7 @@ static inline int NCR5380_pread(struct S
 		while (NCR5380_read(DTC_CONTROL_REG) & CSR_HOST_BUF_NOT_RDY)
 			++i;
 		rtrc(3);
-		memcpy_fromio(d, base + DTC_DATA_BUF, 128);
+		memcpy_fromio(d, hostdata->base + DTC_DATA_BUF, 128);
 		d += 128;
 		len -= 128;
 		rtrc(7);
@@ -377,8 +375,6 @@ static inline int NCR5380_pwrite(struct
 {
 	int i;
 	struct NCR5380_hostdata *hostdata = shost_priv(instance);
-	NCR5380_local_declare();
-	NCR5380_setup(instance);
 
 	NCR5380_read(RESET_PARITY_INTERRUPT_REG);
 	NCR5380_write(MODE_REG, MR_ENABLE_EOP_INTR | MR_DMA_MODE);
@@ -394,7 +390,7 @@ static inline int NCR5380_pwrite(struct
 		while (NCR5380_read(DTC_CONTROL_REG) & CSR_HOST_BUF_NOT_RDY)
 			++i;
 		rtrc(3);
-		memcpy_toio(base + DTC_DATA_BUF, src, 128);
+		memcpy_toio(hostdata->base + DTC_DATA_BUF, src, 128);
 		src += 128;
 		len -= 128;
 	}
@@ -420,15 +416,15 @@ MODULE_LICENSE("GPL");
 
 static int dtc_release(struct Scsi_Host *shost)
 {
-	NCR5380_local_declare();
-	NCR5380_setup(shost);
+	struct NCR5380_hostdata *hostdata = shost_priv(shost);
+
 	if (shost->irq != NO_IRQ)
 		free_irq(shost->irq, shost);
 	NCR5380_exit(shost);
 	if (shost->io_port && shost->n_io_port)
 		release_region(shost->io_port, shost->n_io_port);
 	scsi_unregister(shost);
-	iounmap(base);
+	iounmap(hostdata->base);
 	return 0;
 }
 
Index: linux/drivers/scsi/dtc.h
===================================================================
--- linux.orig/drivers/scsi/dtc.h	2015-11-18 19:33:02.000000000 +1100
+++ linux/drivers/scsi/dtc.h	2015-11-18 19:33:05.000000000 +1100
@@ -21,13 +21,8 @@
 #define NCR5380_implementation_fields \
     void __iomem *base
 
-#define NCR5380_local_declare() \
-    void __iomem *base
-
-#define NCR5380_setup(instance) \
-    base = ((struct NCR5380_hostdata *)(instance)->hostdata)->base
-
-#define DTC_address(reg) (base + DTC_5380_OFFSET + reg)
+#define DTC_address(reg) \
+	(((struct NCR5380_hostdata *)shost_priv(instance))->base + DTC_5380_OFFSET + reg)
 
 #define NCR5380_read(reg) (readb(DTC_address(reg)))
 #define NCR5380_write(reg, value) (writeb(value, DTC_address(reg)))
Index: linux/drivers/scsi/g_NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/g_NCR5380.c	2015-11-18 19:33:04.000000000 +1100
+++ linux/drivers/scsi/g_NCR5380.c	2015-11-18 19:33:05.000000000 +1100
@@ -459,9 +459,6 @@ static int __init generic_NCR5380_detect
  
 static int generic_NCR5380_release_resources(struct Scsi_Host *instance)
 {
-	NCR5380_local_declare();
-	NCR5380_setup(instance);
-	
 	if (instance->irq != NO_IRQ)
 		free_irq(instance->irq, instance);
 	NCR5380_exit(instance);
@@ -520,13 +517,13 @@ generic_NCR5380_biosparam(struct scsi_de
  
 static inline int NCR5380_pread(struct Scsi_Host *instance, unsigned char *dst, int len)
 {
+#ifdef SCSI_G_NCR5380_MEM
+	struct NCR5380_hostdata *hostdata = shost_priv(instance);
+#endif
 	int blocks = len / 128;
 	int start = 0;
 	int bl;
 
-	NCR5380_local_declare();
-	NCR5380_setup(instance);
-
 	NCR5380_write(C400_CONTROL_STATUS_REG, CSR_BASE | CSR_TRANS_DIR);
 	NCR5380_write(C400_BLOCK_COUNTER_REG, blocks);
 	while (1) {
@@ -547,7 +544,8 @@ static inline int NCR5380_pread(struct S
 		}
 #else
 		/* implies SCSI_G_NCR5380_MEM */
-		memcpy_fromio(dst + start, iomem + NCR53C400_host_buffer, 128);
+		memcpy_fromio(dst + start,
+		              hostdata->iomem + NCR53C400_host_buffer, 128);
 #endif
 		start += 128;
 		blocks--;
@@ -567,7 +565,8 @@ static inline int NCR5380_pread(struct S
 		}
 #else
 		/* implies SCSI_G_NCR5380_MEM */
-		memcpy_fromio(dst + start, iomem + NCR53C400_host_buffer, 128);
+		memcpy_fromio(dst + start,
+		              hostdata->iomem + NCR53C400_host_buffer, 128);
 #endif
 		start += 128;
 		blocks--;
@@ -604,14 +603,14 @@ static inline int NCR5380_pread(struct S
 
 static inline int NCR5380_pwrite(struct Scsi_Host *instance, unsigned char *src, int len)
 {
+#ifdef SCSI_G_NCR5380_MEM
+	struct NCR5380_hostdata *hostdata = shost_priv(instance);
+#endif
 	int blocks = len / 128;
 	int start = 0;
 	int bl;
 	int i;
 
-	NCR5380_local_declare();
-	NCR5380_setup(instance);
-
 	NCR5380_write(C400_CONTROL_STATUS_REG, CSR_BASE);
 	NCR5380_write(C400_BLOCK_COUNTER_REG, blocks);
 	while (1) {
@@ -632,7 +631,8 @@ static inline int NCR5380_pwrite(struct
 		}
 #else
 		/* implies SCSI_G_NCR5380_MEM */
-		memcpy_toio(iomem + NCR53C400_host_buffer, src + start, 128);
+		memcpy_toio(hostdata->iomem + NCR53C400_host_buffer,
+		            src + start, 128);
 #endif
 		start += 128;
 		blocks--;
@@ -648,7 +648,8 @@ static inline int NCR5380_pwrite(struct
 		}
 #else
 		/* implies SCSI_G_NCR5380_MEM */
-		memcpy_toio(iomem + NCR53C400_host_buffer, src + start, 128);
+		memcpy_toio(hostdata->iomem + NCR53C400_host_buffer,
+		            src + start, 128);
 #endif
 		start += 128;
 		blocks--;
Index: linux/drivers/scsi/g_NCR5380.h
===================================================================
--- linux.orig/drivers/scsi/g_NCR5380.h	2015-11-18 19:33:04.000000000 +1100
+++ linux/drivers/scsi/g_NCR5380.h	2015-11-18 19:33:05.000000000 +1100
@@ -46,17 +46,12 @@
 #define NCR5380_region_size 8
 #endif
 
-#define NCR5380_read(reg) (inb(NCR5380_map_name + (reg)))
-#define NCR5380_write(reg, value) (outb((value), (NCR5380_map_name + (reg))))
+#define NCR5380_read(reg) \
+	inb(instance->io_port + (reg))
+#define NCR5380_write(reg, value) \
+	outb(value, instance->io_port + (reg))
 
-#define NCR5380_implementation_fields \
-    NCR5380_map_type NCR5380_map_name
-
-#define NCR5380_local_declare() \
-    register NCR5380_implementation_fields
-
-#define NCR5380_setup(instance) \
-    NCR5380_map_name = (NCR5380_map_type)((instance)->NCR5380_instance_name)
+#define NCR5380_implementation_fields /* none */
 
 #else 
 /* therefore SCSI_G_NCR5380_MEM */
@@ -70,19 +65,16 @@
 #define NCR53C400_host_buffer 0x3900
 #define NCR5380_region_size 0x3a00
 
-#define NCR5380_read(reg) readb(iomem + NCR53C400_mem_base + (reg))
-#define NCR5380_write(reg, value) writeb(value, iomem + NCR53C400_mem_base + (reg))
+#define NCR5380_read(reg) \
+	readb(((struct NCR5380_hostdata *)shost_priv(instance))->iomem + \
+	      NCR53C400_mem_base + (reg))
+#define NCR5380_write(reg, value) \
+	writeb(value, ((struct NCR5380_hostdata *)shost_priv(instance))->iomem + \
+	       NCR53C400_mem_base + (reg))
 
 #define NCR5380_implementation_fields \
-    NCR5380_map_type NCR5380_map_name; \
     void __iomem *iomem;
 
-#define NCR5380_local_declare() \
-    register void __iomem *iomem
-
-#define NCR5380_setup(instance) \
-    iomem = (((struct NCR5380_hostdata *)(instance)->hostdata)->iomem)
-
 #endif
 
 #define NCR5380_intr generic_NCR5380_intr
Index: linux/drivers/scsi/mac_scsi.c
===================================================================
--- linux.orig/drivers/scsi/mac_scsi.c	2015-11-18 19:25:56.000000000 +1100
+++ linux/drivers/scsi/mac_scsi.c	2015-11-18 19:33:05.000000000 +1100
@@ -32,11 +32,9 @@
 #define PSEUDO_DMA
 
 #define NCR5380_implementation_fields   unsigned char *pdma_base
-#define NCR5380_local_declare()         struct Scsi_Host *_instance
-#define NCR5380_setup(instance)         _instance = instance
 
-#define NCR5380_read(reg)               macscsi_read(_instance, reg)
-#define NCR5380_write(reg, value)       macscsi_write(_instance, reg, value)
+#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
@@ -129,9 +127,6 @@ static void mac_scsi_reset_boot(struct S
 {
 	unsigned long end;
 
-	NCR5380_local_declare();
-	NCR5380_setup(instance);
-	
 	/*
 	 * Do a SCSI reset to clean up the bus during initialization. No messing
 	 * with the queues, interrupts, or locks necessary here.
@@ -235,9 +230,6 @@ static int macscsi_pread(struct Scsi_Hos
 	unsigned char *d;
 	unsigned char *s;
 
-	NCR5380_local_declare();
-	NCR5380_setup(instance);
-
 	s = hostdata->pdma_base + (INPUT_DATA_REG << 4);
 	d = dst;
 
@@ -329,9 +321,6 @@ static int macscsi_pwrite(struct Scsi_Ho
 	unsigned char *s;
 	unsigned char *d;
 
-	NCR5380_local_declare();
-	NCR5380_setup(instance);
-
 	s = src;
 	d = hostdata->pdma_base + (OUTPUT_DATA_REG << 4);
 
Index: linux/drivers/scsi/pas16.h
===================================================================
--- linux.orig/drivers/scsi/pas16.h	2015-11-18 19:33:04.000000000 +1100
+++ linux/drivers/scsi/pas16.h	2015-11-18 19:33:05.000000000 +1100
@@ -103,16 +103,9 @@
 #define CAN_QUEUE 32 
 #endif
 
-#define NCR5380_implementation_fields \
-    volatile unsigned short io_port
+#define NCR5380_implementation_fields /* none */
 
-#define NCR5380_local_declare() \
-    volatile unsigned short io_port
-
-#define NCR5380_setup(instance) \
-    io_port = (instance)->io_port
-
-#define PAS16_io_port(reg) ( io_port + pas16_offset[(reg)] )
+#define PAS16_io_port(reg) (instance->io_port + pas16_offset[(reg)])
 
 #define NCR5380_read(reg) ( inb(PAS16_io_port(reg)) )
 #define NCR5380_write(reg, value) ( outb((value),PAS16_io_port(reg)) )
Index: linux/drivers/scsi/t128.c
===================================================================
--- linux.orig/drivers/scsi/t128.c	2015-11-18 19:33:02.000000000 +1100
+++ linux/drivers/scsi/t128.c	2015-11-18 19:33:05.000000000 +1100
@@ -248,15 +248,15 @@ found:
 
 static int t128_release(struct Scsi_Host *shost)
 {
-	NCR5380_local_declare();
-	NCR5380_setup(shost);
+	struct NCR5380_hostdata *hostdata = shost_priv(shost);
+
 	if (shost->irq != NO_IRQ)
 		free_irq(shost->irq, shost);
 	NCR5380_exit(shost);
 	if (shost->io_port && shost->n_io_port)
 		release_region(shost->io_port, shost->n_io_port);
 	scsi_unregister(shost);
-	iounmap(base);
+	iounmap(hostdata->base);
 	return 0;
 }
 
@@ -302,14 +302,14 @@ static int t128_biosparam(struct scsi_de
  * 	timeout.
  */
 
-static inline int NCR5380_pread (struct Scsi_Host *instance, unsigned char *dst,
-    int len) {
-    NCR5380_local_declare();
-    void __iomem *reg;
+static inline int
+NCR5380_pread(struct Scsi_Host *instance, unsigned char *dst, int len)
+{
+	struct NCR5380_hostdata *hostdata = shost_priv(instance);
+	void __iomem *reg, *base = hostdata->base;
     unsigned char *d = dst;
     register int i = len;
 
-    NCR5380_setup(instance);
     reg = base + T_DATA_REG_OFFSET;
 
 #if 0
@@ -348,14 +348,14 @@ static inline int NCR5380_pread (struct
  * 	timeout.
  */
 
-static inline int NCR5380_pwrite (struct Scsi_Host *instance, unsigned char *src,
-    int len) {
-    NCR5380_local_declare();
-    void __iomem *reg;
+static inline int
+NCR5380_pwrite(struct Scsi_Host *instance, unsigned char *src, int len)
+{
+	struct NCR5380_hostdata *hostdata = shost_priv(instance);
+	void __iomem *reg, *base = hostdata->base;
     unsigned char *s = src;
     register int i = len;
 
-    NCR5380_setup(instance);
     reg = base + T_DATA_REG_OFFSET;
 
 #if 0
Index: linux/drivers/scsi/t128.h
===================================================================
--- linux.orig/drivers/scsi/t128.h	2015-11-18 19:33:04.000000000 +1100
+++ linux/drivers/scsi/t128.h	2015-11-18 19:33:05.000000000 +1100
@@ -78,13 +78,8 @@
 #define NCR5380_implementation_fields \
     void __iomem *base
 
-#define NCR5380_local_declare() \
-    void __iomem *base
-
-#define NCR5380_setup(instance) \
-    base = ((struct NCR5380_hostdata *)(instance->hostdata))->base
-
-#define T128_address(reg) (base + T_5380_OFFSET + ((reg) * 0x20))
+#define T128_address(reg) \
+	(((struct NCR5380_hostdata *)shost_priv(instance))->base + T_5380_OFFSET + ((reg) * 0x20))
 
 #define NCR5380_read(reg) readb(T128_address(reg))
 #define NCR5380_write(reg, value) writeb((value),(T128_address(reg)))
Index: linux/drivers/scsi/pas16.c
===================================================================
--- linux.orig/drivers/scsi/pas16.c	2015-11-18 19:33:04.000000000 +1100
+++ linux/drivers/scsi/pas16.c	2015-11-18 19:33:05.000000000 +1100
@@ -188,7 +188,7 @@ static void __init
 	outb( 0x01, io_port + P_TIMEOUT_STATUS_REG_OFFSET );   /* Reset TC */
 	outb( 0x01, io_port + WAIT_STATE );   /* 1 Wait state */
 
-	NCR5380_read( RESET_PARITY_INTERRUPT_REG );
+	inb(io_port + pas16_offset[RESET_PARITY_INTERRUPT_REG]);
 
 	/* Set the SCSI interrupt pointer without mucking up the sound
 	 * interrupt pointer in the same byte.
@@ -263,13 +263,13 @@ static int __init
      * put in an additional test to try to weed them out.
      */
 
-    outb( 0x01, io_port + WAIT_STATE ); 	/* 1 Wait state */
-    NCR5380_write( MODE_REG, 0x20 );		/* Is it really SCSI? */
-    if( NCR5380_read( MODE_REG ) != 0x20 )	/* Write to a reg.    */
-	return 0;				/* and try to read    */
-    NCR5380_write( MODE_REG, 0x00 );		/* it back.	      */
-    if( NCR5380_read( MODE_REG ) != 0x00 )
-	return 0;
+	outb(0x01, io_port + WAIT_STATE);             /* 1 Wait state */
+	outb(0x20, io_port + pas16_offset[MODE_REG]); /* Is it really SCSI? */
+	if (inb(io_port + pas16_offset[MODE_REG]) != 0x20) /* Write to a reg. */
+		return 0;                                  /* and try to read */
+	outb(0x00, io_port + pas16_offset[MODE_REG]);      /* it back. */
+	if (inb(io_port + pas16_offset[MODE_REG]) != 0x00)
+		return 0;
 
     return 1;
 }

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

* [PATCH 05/71] ncr5380: Remove NCR5380_local_declare and NCR5380_setup macros
@ 2015-11-18  8:35   ` Finn Thain
  0 siblings, 0 replies; 268+ messages in thread
From: Finn Thain @ 2015-11-18  8:35 UTC (permalink / raw)
  To: linux-arm-kernel

An embedded and charset-unspecified text was scrubbed...
Name: ncr5380-eliminate-local_declare-macros
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20151118/1436c36a/attachment.ksh>

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

* [PATCH 06/71] ncr5380: Remove NCR5380_instance_name macro
  2015-11-18  8:34 ` Finn Thain
@ 2015-11-18  8:35   ` Finn Thain
  -1 siblings, 0 replies; 268+ messages in thread
From: Finn Thain @ 2015-11-18  8:35 UTC (permalink / raw)
  To: James E.J. Bottomley, Michael Schmitz, linux-m68k, linux-scsi,
	linux-kernel

[-- Attachment #1: ncr5380-remove-NCR5380_instance_name --]
[-- Type: text/plain, Size: 2642 bytes --]

This macro makes the code cryptic. Remove it.

Signed-off-by: Finn Thain <fthain@telegraphics.com.au>

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

Index: linux/drivers/scsi/g_NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/g_NCR5380.c	2015-11-18 19:33:05.000000000 +1100
+++ linux/drivers/scsi/g_NCR5380.c	2015-11-18 19:33:09.000000000 +1100
@@ -412,10 +412,11 @@ static int __init generic_NCR5380_detect
 			continue;
 		}
 
-		instance->NCR5380_instance_name = overrides[current_override].NCR5380_map_name;
 #ifndef SCSI_G_NCR5380_MEM
+		instance->io_port = overrides[current_override].NCR5380_map_name;
 		instance->n_io_port = region_size;
 #else
+		instance->base = overrides[current_override].NCR5380_map_name;
 		((struct NCR5380_hostdata *)instance->hostdata)->iomem = iomem;
 #endif
 
@@ -464,10 +465,10 @@ static int generic_NCR5380_release_resou
 	NCR5380_exit(instance);
 
 #ifndef SCSI_G_NCR5380_MEM
-	release_region(instance->NCR5380_instance_name, instance->n_io_port);
+	release_region(instance->io_port, instance->n_io_port);
 #else
 	iounmap(((struct NCR5380_hostdata *)instance->hostdata)->iomem);
-	release_mem_region(instance->NCR5380_instance_name, NCR5380_region_size);
+	release_mem_region(instance->base, NCR5380_region_size);
 #endif
 
 
Index: linux/drivers/scsi/g_NCR5380.h
===================================================================
--- linux.orig/drivers/scsi/g_NCR5380.h	2015-11-18 19:33:05.000000000 +1100
+++ linux/drivers/scsi/g_NCR5380.h	2015-11-18 19:33:09.000000000 +1100
@@ -36,7 +36,6 @@
 
 #define NCR5380_map_type int
 #define NCR5380_map_name port
-#define NCR5380_instance_name io_port
 #define NCR53C400_register_offset 0
 #define NCR53C400_address_adjust 8
 
@@ -58,7 +57,6 @@
 
 #define NCR5380_map_type unsigned long
 #define NCR5380_map_name base
-#define NCR5380_instance_name base
 #define NCR53C400_register_offset 0x108
 #define NCR53C400_address_adjust 0
 #define NCR53C400_mem_base 0x3880
Index: linux/drivers/scsi/NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/NCR5380.c	2015-11-18 19:33:05.000000000 +1100
+++ linux/drivers/scsi/NCR5380.c	2015-11-18 19:33:09.000000000 +1100
@@ -790,7 +790,7 @@ static int NCR5380_init(struct Scsi_Host
 
 #ifdef NCR53C400
 	if (flags & FLAG_NCR53C400)
-		instance->NCR5380_instance_name += NCR53C400_address_adjust;
+		instance->io_port += NCR53C400_address_adjust;
 #endif
 
 	hostdata->aborted = 0;



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

* [PATCH 06/71] ncr5380: Remove NCR5380_instance_name macro
@ 2015-11-18  8:35   ` Finn Thain
  0 siblings, 0 replies; 268+ messages in thread
From: Finn Thain @ 2015-11-18  8:35 UTC (permalink / raw)
  To: James E.J. Bottomley, Michael Schmitz, linux-m68k, linux-scsi,
	linux-kernel

[-- Attachment #1: ncr5380-remove-NCR5380_instance_name --]
[-- Type: text/plain, Size: 2640 bytes --]

This macro makes the code cryptic. Remove it.

Signed-off-by: Finn Thain <fthain@telegraphics.com.au>

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

Index: linux/drivers/scsi/g_NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/g_NCR5380.c	2015-11-18 19:33:05.000000000 +1100
+++ linux/drivers/scsi/g_NCR5380.c	2015-11-18 19:33:09.000000000 +1100
@@ -412,10 +412,11 @@ static int __init generic_NCR5380_detect
 			continue;
 		}
 
-		instance->NCR5380_instance_name = overrides[current_override].NCR5380_map_name;
 #ifndef SCSI_G_NCR5380_MEM
+		instance->io_port = overrides[current_override].NCR5380_map_name;
 		instance->n_io_port = region_size;
 #else
+		instance->base = overrides[current_override].NCR5380_map_name;
 		((struct NCR5380_hostdata *)instance->hostdata)->iomem = iomem;
 #endif
 
@@ -464,10 +465,10 @@ static int generic_NCR5380_release_resou
 	NCR5380_exit(instance);
 
 #ifndef SCSI_G_NCR5380_MEM
-	release_region(instance->NCR5380_instance_name, instance->n_io_port);
+	release_region(instance->io_port, instance->n_io_port);
 #else
 	iounmap(((struct NCR5380_hostdata *)instance->hostdata)->iomem);
-	release_mem_region(instance->NCR5380_instance_name, NCR5380_region_size);
+	release_mem_region(instance->base, NCR5380_region_size);
 #endif
 
 
Index: linux/drivers/scsi/g_NCR5380.h
===================================================================
--- linux.orig/drivers/scsi/g_NCR5380.h	2015-11-18 19:33:05.000000000 +1100
+++ linux/drivers/scsi/g_NCR5380.h	2015-11-18 19:33:09.000000000 +1100
@@ -36,7 +36,6 @@
 
 #define NCR5380_map_type int
 #define NCR5380_map_name port
-#define NCR5380_instance_name io_port
 #define NCR53C400_register_offset 0
 #define NCR53C400_address_adjust 8
 
@@ -58,7 +57,6 @@
 
 #define NCR5380_map_type unsigned long
 #define NCR5380_map_name base
-#define NCR5380_instance_name base
 #define NCR53C400_register_offset 0x108
 #define NCR53C400_address_adjust 0
 #define NCR53C400_mem_base 0x3880
Index: linux/drivers/scsi/NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/NCR5380.c	2015-11-18 19:33:05.000000000 +1100
+++ linux/drivers/scsi/NCR5380.c	2015-11-18 19:33:09.000000000 +1100
@@ -790,7 +790,7 @@ static int NCR5380_init(struct Scsi_Host
 
 #ifdef NCR53C400
 	if (flags & FLAG_NCR53C400)
-		instance->NCR5380_instance_name += NCR53C400_address_adjust;
+		instance->io_port += NCR53C400_address_adjust;
 #endif
 
 	hostdata->aborted = 0;

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

* [PATCH 07/71] ncr5380: Split NCR5380_init() into two functions
  2015-11-18  8:34 ` Finn Thain
  (?)
@ 2015-11-18  8:35   ` Finn Thain
  -1 siblings, 0 replies; 268+ messages in thread
From: Finn Thain @ 2015-11-18  8:35 UTC (permalink / raw)
  To: James E.J. Bottomley, Michael Schmitz, linux-m68k, linux-scsi,
	linux-kernel, Russell King, linux-arm-kernel

[-- Attachment #1: ncr5380-bus-wedge --]
[-- Type: text/plain, Size: 7408 bytes --]

This patch splits the NCR5380_init() function into two parts, similar
to the scheme used with atari_NCR5380.c. This avoids two problems.

Firstly, NCR5380_init() may perform a bus reset, which would cause the
chip to assert IRQ. The chip is unable to mask its bus reset interrupt.
Drivers can't call request_irq() before calling NCR5380_init(), because
initialization must happen before the interrupt handler executes. If
driver initialization causes an interrupt it may be problematic on some
platforms. To avoid that, first move the bus reset code into
NCR5380_maybe_reset_bus().

Secondly, NCR5380_init() contains some board-specific interrupt setup code
for the NCR53C400 that does not belong in the core driver. In moving this
code, better not re-order interrupt initialization and bus reset. Again,
the solution is to move the bus reset code into NCR5380_maybe_reset_bus().

Signed-off-by: Finn Thain <fthain@telegraphics.com.au>

---
 drivers/scsi/NCR5380.c      |   34 ++++++++++++++++++++--------------
 drivers/scsi/NCR5380.h      |    1 +
 drivers/scsi/arm/cumana_1.c |    2 ++
 drivers/scsi/arm/oak.c      |    2 ++
 drivers/scsi/dmx3191d.c     |    2 ++
 drivers/scsi/dtc.c          |    2 ++
 drivers/scsi/g_NCR5380.c    |    2 ++
 drivers/scsi/pas16.c        |    2 ++
 drivers/scsi/t128.c         |    2 ++
 9 files changed, 35 insertions(+), 14 deletions(-)

Index: linux/drivers/scsi/NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/NCR5380.c	2015-11-18 19:33:09.000000000 +1100
+++ linux/drivers/scsi/NCR5380.c	2015-11-18 19:33:10.000000000 +1100
@@ -777,8 +777,7 @@ static void lprint_opcode(int opcode, st
 
 static int NCR5380_init(struct Scsi_Host *instance, int flags)
 {
-	int i, pass;
-	unsigned long timeout;
+	int i;
 	struct NCR5380_hostdata *hostdata = (struct NCR5380_hostdata *) instance->hostdata;
 
 	if(in_interrupt())
@@ -831,18 +830,26 @@ static int NCR5380_init(struct Scsi_Host
 		NCR5380_write(C400_CONTROL_STATUS_REG, CSR_BASE);
 	}
 #endif
+	return 0;
+}
 
-	/* 
-	 * Detect and correct bus wedge problems.
-	 *
-	 * If the system crashed, it may have crashed in a state 
-	 * where a SCSI command was still executing, and the 
-	 * SCSI bus is not in a BUS FREE STATE.
-	 *
-	 * If this is the case, we'll try to abort the currently
-	 * established nexus which we know nothing about, and that
-	 * failing, do a hard reset of the SCSI bus 
-	 */
+/**
+ * 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)
+{
+	int pass;
 
 	for (pass = 1; (NCR5380_read(STATUS_REG) & SR_BSY) && pass <= 6; ++pass) {
 		switch (pass) {
@@ -850,7 +857,6 @@ static int NCR5380_init(struct Scsi_Host
 		case 3:
 		case 5:
 			printk(KERN_INFO "scsi%d: SCSI bus busy, waiting up to five seconds\n", instance->host_no);
-			timeout = jiffies + 5 * HZ;
 			NCR5380_poll_politely(instance, STATUS_REG, SR_BSY, 0, 5*HZ);
 			break;
 		case 2:
Index: linux/drivers/scsi/NCR5380.h
===================================================================
--- linux.orig/drivers/scsi/NCR5380.h	2015-11-18 19:33:04.000000000 +1100
+++ linux/drivers/scsi/NCR5380.h	2015-11-18 19:33:10.000000000 +1100
@@ -318,6 +318,7 @@ static void NCR5380_print(struct Scsi_Ho
 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
Index: linux/drivers/scsi/arm/cumana_1.c
===================================================================
--- linux.orig/drivers/scsi/arm/cumana_1.c	2015-11-18 19:33:05.000000000 +1100
+++ linux/drivers/scsi/arm/cumana_1.c	2015-11-18 19:33:10.000000000 +1100
@@ -240,6 +240,8 @@ static int cumanascsi1_probe(struct expa
 
 	NCR5380_init(host, 0);
 
+	NCR5380_maybe_reset_bus(host);
+
         priv(host)->ctrl = 0;
         writeb(0, priv(host)->base + CTRL);
 
Index: linux/drivers/scsi/arm/oak.c
===================================================================
--- linux.orig/drivers/scsi/arm/oak.c	2015-11-18 19:33:05.000000000 +1100
+++ linux/drivers/scsi/arm/oak.c	2015-11-18 19:33:10.000000000 +1100
@@ -145,6 +145,8 @@ static int oakscsi_probe(struct expansio
 
 	NCR5380_init(host, 0);
 
+	NCR5380_maybe_reset_bus(host);
+
 	ret = scsi_add_host(host, &ec->dev);
 	if (ret)
 		goto out_unmap;
Index: linux/drivers/scsi/dmx3191d.c
===================================================================
--- linux.orig/drivers/scsi/dmx3191d.c	2015-11-18 19:33:05.000000000 +1100
+++ linux/drivers/scsi/dmx3191d.c	2015-11-18 19:33:10.000000000 +1100
@@ -97,6 +97,8 @@ static int dmx3191d_probe_one(struct pci
 
 	NCR5380_init(shost, FLAG_NO_PSEUDO_DMA | FLAG_DTC3181E);
 
+	NCR5380_maybe_reset_bus(shost);
+
 	pci_set_drvdata(pdev, shost);
 
 	error = scsi_add_host(shost, &pdev->dev);
Index: linux/drivers/scsi/dtc.c
===================================================================
--- linux.orig/drivers/scsi/dtc.c	2015-11-18 19:33:05.000000000 +1100
+++ linux/drivers/scsi/dtc.c	2015-11-18 19:33:10.000000000 +1100
@@ -237,6 +237,8 @@ found:
 
 		NCR5380_init(instance, 0);
 
+		NCR5380_maybe_reset_bus(instance);
+
 		NCR5380_write(DTC_CONTROL_REG, CSR_5380_INTR);	/* Enable int's */
 		if (overrides[current_override].irq != IRQ_AUTO)
 			instance->irq = overrides[current_override].irq;
Index: linux/drivers/scsi/g_NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/g_NCR5380.c	2015-11-18 19:33:09.000000000 +1100
+++ linux/drivers/scsi/g_NCR5380.c	2015-11-18 19:33:10.000000000 +1100
@@ -422,6 +422,8 @@ static int __init generic_NCR5380_detect
 
 		NCR5380_init(instance, flags);
 
+		NCR5380_maybe_reset_bus(instance);
+
 		if (overrides[current_override].irq != IRQ_AUTO)
 			instance->irq = overrides[current_override].irq;
 		else
Index: linux/drivers/scsi/pas16.c
===================================================================
--- linux.orig/drivers/scsi/pas16.c	2015-11-18 19:33:05.000000000 +1100
+++ linux/drivers/scsi/pas16.c	2015-11-18 19:33:10.000000000 +1100
@@ -384,6 +384,8 @@ static int __init pas16_detect(struct sc
 
 	NCR5380_init(instance, 0);
 
+	NCR5380_maybe_reset_bus(instance);
+
 	if (overrides[current_override].irq != IRQ_AUTO)
 	    instance->irq = overrides[current_override].irq;
 	else 
Index: linux/drivers/scsi/t128.c
===================================================================
--- linux.orig/drivers/scsi/t128.c	2015-11-18 19:33:05.000000000 +1100
+++ linux/drivers/scsi/t128.c	2015-11-18 19:33:10.000000000 +1100
@@ -215,6 +215,8 @@ found:
 
 	NCR5380_init(instance, 0);
 
+	NCR5380_maybe_reset_bus(instance);
+
 	if (overrides[current_override].irq != IRQ_AUTO)
 	    instance->irq = overrides[current_override].irq;
 	else 



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

* [PATCH 07/71] ncr5380: Split NCR5380_init() into two functions
@ 2015-11-18  8:35   ` Finn Thain
  0 siblings, 0 replies; 268+ messages in thread
From: Finn Thain @ 2015-11-18  8:35 UTC (permalink / raw)
  To: James E.J. Bottomley, Michael Schmitz, linux-m68k, linux-scsi,
	linux-kernel, Russell King, linux-arm-kernel

[-- Attachment #1: ncr5380-bus-wedge --]
[-- Type: text/plain, Size: 7406 bytes --]

This patch splits the NCR5380_init() function into two parts, similar
to the scheme used with atari_NCR5380.c. This avoids two problems.

Firstly, NCR5380_init() may perform a bus reset, which would cause the
chip to assert IRQ. The chip is unable to mask its bus reset interrupt.
Drivers can't call request_irq() before calling NCR5380_init(), because
initialization must happen before the interrupt handler executes. If
driver initialization causes an interrupt it may be problematic on some
platforms. To avoid that, first move the bus reset code into
NCR5380_maybe_reset_bus().

Secondly, NCR5380_init() contains some board-specific interrupt setup code
for the NCR53C400 that does not belong in the core driver. In moving this
code, better not re-order interrupt initialization and bus reset. Again,
the solution is to move the bus reset code into NCR5380_maybe_reset_bus().

Signed-off-by: Finn Thain <fthain@telegraphics.com.au>

---
 drivers/scsi/NCR5380.c      |   34 ++++++++++++++++++++--------------
 drivers/scsi/NCR5380.h      |    1 +
 drivers/scsi/arm/cumana_1.c |    2 ++
 drivers/scsi/arm/oak.c      |    2 ++
 drivers/scsi/dmx3191d.c     |    2 ++
 drivers/scsi/dtc.c          |    2 ++
 drivers/scsi/g_NCR5380.c    |    2 ++
 drivers/scsi/pas16.c        |    2 ++
 drivers/scsi/t128.c         |    2 ++
 9 files changed, 35 insertions(+), 14 deletions(-)

Index: linux/drivers/scsi/NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/NCR5380.c	2015-11-18 19:33:09.000000000 +1100
+++ linux/drivers/scsi/NCR5380.c	2015-11-18 19:33:10.000000000 +1100
@@ -777,8 +777,7 @@ static void lprint_opcode(int opcode, st
 
 static int NCR5380_init(struct Scsi_Host *instance, int flags)
 {
-	int i, pass;
-	unsigned long timeout;
+	int i;
 	struct NCR5380_hostdata *hostdata = (struct NCR5380_hostdata *) instance->hostdata;
 
 	if(in_interrupt())
@@ -831,18 +830,26 @@ static int NCR5380_init(struct Scsi_Host
 		NCR5380_write(C400_CONTROL_STATUS_REG, CSR_BASE);
 	}
 #endif
+	return 0;
+}
 
-	/* 
-	 * Detect and correct bus wedge problems.
-	 *
-	 * If the system crashed, it may have crashed in a state 
-	 * where a SCSI command was still executing, and the 
-	 * SCSI bus is not in a BUS FREE STATE.
-	 *
-	 * If this is the case, we'll try to abort the currently
-	 * established nexus which we know nothing about, and that
-	 * failing, do a hard reset of the SCSI bus 
-	 */
+/**
+ * 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)
+{
+	int pass;
 
 	for (pass = 1; (NCR5380_read(STATUS_REG) & SR_BSY) && pass <= 6; ++pass) {
 		switch (pass) {
@@ -850,7 +857,6 @@ static int NCR5380_init(struct Scsi_Host
 		case 3:
 		case 5:
 			printk(KERN_INFO "scsi%d: SCSI bus busy, waiting up to five seconds\n", instance->host_no);
-			timeout = jiffies + 5 * HZ;
 			NCR5380_poll_politely(instance, STATUS_REG, SR_BSY, 0, 5*HZ);
 			break;
 		case 2:
Index: linux/drivers/scsi/NCR5380.h
===================================================================
--- linux.orig/drivers/scsi/NCR5380.h	2015-11-18 19:33:04.000000000 +1100
+++ linux/drivers/scsi/NCR5380.h	2015-11-18 19:33:10.000000000 +1100
@@ -318,6 +318,7 @@ static void NCR5380_print(struct Scsi_Ho
 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
Index: linux/drivers/scsi/arm/cumana_1.c
===================================================================
--- linux.orig/drivers/scsi/arm/cumana_1.c	2015-11-18 19:33:05.000000000 +1100
+++ linux/drivers/scsi/arm/cumana_1.c	2015-11-18 19:33:10.000000000 +1100
@@ -240,6 +240,8 @@ static int cumanascsi1_probe(struct expa
 
 	NCR5380_init(host, 0);
 
+	NCR5380_maybe_reset_bus(host);
+
         priv(host)->ctrl = 0;
         writeb(0, priv(host)->base + CTRL);
 
Index: linux/drivers/scsi/arm/oak.c
===================================================================
--- linux.orig/drivers/scsi/arm/oak.c	2015-11-18 19:33:05.000000000 +1100
+++ linux/drivers/scsi/arm/oak.c	2015-11-18 19:33:10.000000000 +1100
@@ -145,6 +145,8 @@ static int oakscsi_probe(struct expansio
 
 	NCR5380_init(host, 0);
 
+	NCR5380_maybe_reset_bus(host);
+
 	ret = scsi_add_host(host, &ec->dev);
 	if (ret)
 		goto out_unmap;
Index: linux/drivers/scsi/dmx3191d.c
===================================================================
--- linux.orig/drivers/scsi/dmx3191d.c	2015-11-18 19:33:05.000000000 +1100
+++ linux/drivers/scsi/dmx3191d.c	2015-11-18 19:33:10.000000000 +1100
@@ -97,6 +97,8 @@ static int dmx3191d_probe_one(struct pci
 
 	NCR5380_init(shost, FLAG_NO_PSEUDO_DMA | FLAG_DTC3181E);
 
+	NCR5380_maybe_reset_bus(shost);
+
 	pci_set_drvdata(pdev, shost);
 
 	error = scsi_add_host(shost, &pdev->dev);
Index: linux/drivers/scsi/dtc.c
===================================================================
--- linux.orig/drivers/scsi/dtc.c	2015-11-18 19:33:05.000000000 +1100
+++ linux/drivers/scsi/dtc.c	2015-11-18 19:33:10.000000000 +1100
@@ -237,6 +237,8 @@ found:
 
 		NCR5380_init(instance, 0);
 
+		NCR5380_maybe_reset_bus(instance);
+
 		NCR5380_write(DTC_CONTROL_REG, CSR_5380_INTR);	/* Enable int's */
 		if (overrides[current_override].irq != IRQ_AUTO)
 			instance->irq = overrides[current_override].irq;
Index: linux/drivers/scsi/g_NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/g_NCR5380.c	2015-11-18 19:33:09.000000000 +1100
+++ linux/drivers/scsi/g_NCR5380.c	2015-11-18 19:33:10.000000000 +1100
@@ -422,6 +422,8 @@ static int __init generic_NCR5380_detect
 
 		NCR5380_init(instance, flags);
 
+		NCR5380_maybe_reset_bus(instance);
+
 		if (overrides[current_override].irq != IRQ_AUTO)
 			instance->irq = overrides[current_override].irq;
 		else
Index: linux/drivers/scsi/pas16.c
===================================================================
--- linux.orig/drivers/scsi/pas16.c	2015-11-18 19:33:05.000000000 +1100
+++ linux/drivers/scsi/pas16.c	2015-11-18 19:33:10.000000000 +1100
@@ -384,6 +384,8 @@ static int __init pas16_detect(struct sc
 
 	NCR5380_init(instance, 0);
 
+	NCR5380_maybe_reset_bus(instance);
+
 	if (overrides[current_override].irq != IRQ_AUTO)
 	    instance->irq = overrides[current_override].irq;
 	else 
Index: linux/drivers/scsi/t128.c
===================================================================
--- linux.orig/drivers/scsi/t128.c	2015-11-18 19:33:05.000000000 +1100
+++ linux/drivers/scsi/t128.c	2015-11-18 19:33:10.000000000 +1100
@@ -215,6 +215,8 @@ found:
 
 	NCR5380_init(instance, 0);
 
+	NCR5380_maybe_reset_bus(instance);
+
 	if (overrides[current_override].irq != IRQ_AUTO)
 	    instance->irq = overrides[current_override].irq;
 	else 

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

* [PATCH 07/71] ncr5380: Split NCR5380_init() into two functions
@ 2015-11-18  8:35   ` Finn Thain
  0 siblings, 0 replies; 268+ messages in thread
From: Finn Thain @ 2015-11-18  8:35 UTC (permalink / raw)
  To: linux-arm-kernel

An embedded and charset-unspecified text was scrubbed...
Name: ncr5380-bus-wedge
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20151118/1ae98848/attachment.ksh>

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

* [PATCH 08/71] ncr5380: Move NCR53C400-specific code
  2015-11-18  8:34 ` Finn Thain
@ 2015-11-18  8:35   ` Finn Thain
  -1 siblings, 0 replies; 268+ messages in thread
From: Finn Thain @ 2015-11-18  8:35 UTC (permalink / raw)
  To: James E.J. Bottomley, Michael Schmitz, linux-m68k, linux-scsi,
	linux-kernel

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

Move board-specific code like this,
	NCR5380_write(C400_CONTROL_STATUS_REG, CSR_BASE);
from the core driver to the board driver. Eliminate the NCR53C400 macro
from the core driver. Removal of all macros like this one will be
necessary in order to have one core driver that can support all kinds of
boards.

Signed-off-by: Finn Thain <fthain@telegraphics.com.au>

---
 drivers/scsi/NCR5380.c   |   18 ------------------
 drivers/scsi/g_NCR5380.c |   23 ++++++++++++++++++-----
 drivers/scsi/g_NCR5380.h |    6 ++----
 3 files changed, 20 insertions(+), 27 deletions(-)

Index: linux/drivers/scsi/NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/NCR5380.c	2015-11-18 19:33:10.000000000 +1100
+++ linux/drivers/scsi/NCR5380.c	2015-11-18 19:33:12.000000000 +1100
@@ -654,9 +654,6 @@ static void prepare_info(struct Scsi_Hos
 #ifdef UNSAFE
 	         "UNSAFE "
 #endif
-#ifdef NCR53C400
-	         "NCR53C400 "
-#endif
 	         "");
 }
 
@@ -782,15 +779,6 @@ static int NCR5380_init(struct Scsi_Host
 
 	if(in_interrupt())
 		printk(KERN_ERR "NCR5380_init called with interrupts off!\n");
-	/* 
-	 * On NCR53C400 boards, NCR5380 registers are mapped 8 past 
-	 * the base address.
-	 */
-
-#ifdef NCR53C400
-	if (flags & FLAG_NCR53C400)
-		instance->io_port += NCR53C400_address_adjust;
-#endif
 
 	hostdata->aborted = 0;
 	hostdata->id_mask = 1 << instance->this_id;
@@ -824,12 +812,6 @@ static int NCR5380_init(struct Scsi_Host
 	NCR5380_write(MODE_REG, MR_BASE);
 	NCR5380_write(TARGET_COMMAND_REG, 0);
 	NCR5380_write(SELECT_ENABLE_REG, 0);
-
-#ifdef NCR53C400
-	if (hostdata->flags & FLAG_NCR53C400) {
-		NCR5380_write(C400_CONTROL_STATUS_REG, CSR_BASE);
-	}
-#endif
 	return 0;
 }
 
Index: linux/drivers/scsi/g_NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/g_NCR5380.c	2015-11-18 19:33:10.000000000 +1100
+++ linux/drivers/scsi/g_NCR5380.c	2015-11-18 19:33:12.000000000 +1100
@@ -64,9 +64,7 @@
 #define AUTOPROBE_IRQ
 
 #ifdef CONFIG_SCSI_GENERIC_NCR53C400
-#define NCR53C400_PSEUDO_DMA 1
 #define PSEUDO_DMA
-#define NCR53C400
 #endif
 
 #include <asm/io.h>
@@ -263,7 +261,7 @@ static int __init generic_NCR5380_detect
 	static unsigned int __initdata dtc_3181e_ports[] = {
 		0x220, 0x240, 0x280, 0x2a0, 0x2c0, 0x300, 0x320, 0x340, 0
 	};
-	int flags = 0;
+	int flags;
 	struct Scsi_Host *instance;
 #ifdef SCSI_G_NCR5380_MEM
 	unsigned long base;
@@ -324,12 +322,17 @@ static int __init generic_NCR5380_detect
 			continue;
 
 		ports = NULL;
+		flags = 0;
 		switch (overrides[current_override].board) {
 		case BOARD_NCR5380:
 			flags = FLAG_NO_PSEUDO_DMA;
 			break;
 		case BOARD_NCR53C400:
+#ifdef PSEUDO_DMA
 			flags = FLAG_NCR53C400;
+#else
+			flags = FLAG_NO_PSEUDO_DMA;
+#endif
 			break;
 		case BOARD_NCR53C400A:
 			flags = FLAG_NO_PSEUDO_DMA;
@@ -415,6 +418,13 @@ static int __init generic_NCR5380_detect
 #ifndef SCSI_G_NCR5380_MEM
 		instance->io_port = overrides[current_override].NCR5380_map_name;
 		instance->n_io_port = region_size;
+
+		/*
+		 * On NCR53C400 boards, NCR5380 registers are mapped 8 past
+		 * the base address.
+		 */
+		if (overrides[current_override].board == BOARD_NCR53C400)
+			instance->io_port += 8;
 #else
 		instance->base = overrides[current_override].NCR5380_map_name;
 		((struct NCR5380_hostdata *)instance->hostdata)->iomem = iomem;
@@ -422,6 +432,9 @@ static int __init generic_NCR5380_detect
 
 		NCR5380_init(instance, flags);
 
+		if (overrides[current_override].board == BOARD_NCR53C400)
+			NCR5380_write(C400_CONTROL_STATUS_REG, CSR_BASE);
+
 		NCR5380_maybe_reset_bus(instance);
 
 		if (overrides[current_override].irq != IRQ_AUTO)
@@ -506,7 +519,7 @@ generic_NCR5380_biosparam(struct scsi_de
 }
 #endif
 
-#ifdef NCR53C400_PSEUDO_DMA
+#ifdef PSEUDO_DMA
 
 /**
  *	NCR5380_pread		-	pseudo DMA read
@@ -690,7 +703,7 @@ static inline int NCR5380_pwrite(struct
 		; 	// TIMEOUT
 	return 0;
 }
-#endif				/* PSEUDO_DMA */
+#endif /* PSEUDO_DMA */
 
 /*
  *	Include the NCR5380 core code that we build our driver around	
Index: linux/drivers/scsi/g_NCR5380.h
===================================================================
--- linux.orig/drivers/scsi/g_NCR5380.h	2015-11-18 19:33:09.000000000 +1100
+++ linux/drivers/scsi/g_NCR5380.h	2015-11-18 19:33:12.000000000 +1100
@@ -14,7 +14,7 @@
 #ifndef GENERIC_NCR5380_H
 #define GENERIC_NCR5380_H
 
-#ifdef NCR53C400
+#ifdef CONFIG_SCSI_GENERIC_NCR53C400
 #define BIOSPARAM
 #define NCR5380_BIOSPARAM generic_NCR5380_biosparam
 #else
@@ -37,9 +37,8 @@
 #define NCR5380_map_type int
 #define NCR5380_map_name port
 #define NCR53C400_register_offset 0
-#define NCR53C400_address_adjust 8
 
-#ifdef NCR53C400
+#ifdef CONFIG_SCSI_GENERIC_NCR53C400
 #define NCR5380_region_size 16
 #else
 #define NCR5380_region_size 8
@@ -58,7 +57,6 @@
 #define NCR5380_map_type unsigned long
 #define NCR5380_map_name base
 #define NCR53C400_register_offset 0x108
-#define NCR53C400_address_adjust 0
 #define NCR53C400_mem_base 0x3880
 #define NCR53C400_host_buffer 0x3900
 #define NCR5380_region_size 0x3a00



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

* [PATCH 08/71] ncr5380: Move NCR53C400-specific code
@ 2015-11-18  8:35   ` Finn Thain
  0 siblings, 0 replies; 268+ messages in thread
From: Finn Thain @ 2015-11-18  8:35 UTC (permalink / raw)
  To: James E.J. Bottomley, Michael Schmitz, linux-m68k, linux-scsi,
	linux-kernel

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

Move board-specific code like this,
	NCR5380_write(C400_CONTROL_STATUS_REG, CSR_BASE);
from the core driver to the board driver. Eliminate the NCR53C400 macro
from the core driver. Removal of all macros like this one will be
necessary in order to have one core driver that can support all kinds of
boards.

Signed-off-by: Finn Thain <fthain@telegraphics.com.au>

---
 drivers/scsi/NCR5380.c   |   18 ------------------
 drivers/scsi/g_NCR5380.c |   23 ++++++++++++++++++-----
 drivers/scsi/g_NCR5380.h |    6 ++----
 3 files changed, 20 insertions(+), 27 deletions(-)

Index: linux/drivers/scsi/NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/NCR5380.c	2015-11-18 19:33:10.000000000 +1100
+++ linux/drivers/scsi/NCR5380.c	2015-11-18 19:33:12.000000000 +1100
@@ -654,9 +654,6 @@ static void prepare_info(struct Scsi_Hos
 #ifdef UNSAFE
 	         "UNSAFE "
 #endif
-#ifdef NCR53C400
-	         "NCR53C400 "
-#endif
 	         "");
 }
 
@@ -782,15 +779,6 @@ static int NCR5380_init(struct Scsi_Host
 
 	if(in_interrupt())
 		printk(KERN_ERR "NCR5380_init called with interrupts off!\n");
-	/* 
-	 * On NCR53C400 boards, NCR5380 registers are mapped 8 past 
-	 * the base address.
-	 */
-
-#ifdef NCR53C400
-	if (flags & FLAG_NCR53C400)
-		instance->io_port += NCR53C400_address_adjust;
-#endif
 
 	hostdata->aborted = 0;
 	hostdata->id_mask = 1 << instance->this_id;
@@ -824,12 +812,6 @@ static int NCR5380_init(struct Scsi_Host
 	NCR5380_write(MODE_REG, MR_BASE);
 	NCR5380_write(TARGET_COMMAND_REG, 0);
 	NCR5380_write(SELECT_ENABLE_REG, 0);
-
-#ifdef NCR53C400
-	if (hostdata->flags & FLAG_NCR53C400) {
-		NCR5380_write(C400_CONTROL_STATUS_REG, CSR_BASE);
-	}
-#endif
 	return 0;
 }
 
Index: linux/drivers/scsi/g_NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/g_NCR5380.c	2015-11-18 19:33:10.000000000 +1100
+++ linux/drivers/scsi/g_NCR5380.c	2015-11-18 19:33:12.000000000 +1100
@@ -64,9 +64,7 @@
 #define AUTOPROBE_IRQ
 
 #ifdef CONFIG_SCSI_GENERIC_NCR53C400
-#define NCR53C400_PSEUDO_DMA 1
 #define PSEUDO_DMA
-#define NCR53C400
 #endif
 
 #include <asm/io.h>
@@ -263,7 +261,7 @@ static int __init generic_NCR5380_detect
 	static unsigned int __initdata dtc_3181e_ports[] = {
 		0x220, 0x240, 0x280, 0x2a0, 0x2c0, 0x300, 0x320, 0x340, 0
 	};
-	int flags = 0;
+	int flags;
 	struct Scsi_Host *instance;
 #ifdef SCSI_G_NCR5380_MEM
 	unsigned long base;
@@ -324,12 +322,17 @@ static int __init generic_NCR5380_detect
 			continue;
 
 		ports = NULL;
+		flags = 0;
 		switch (overrides[current_override].board) {
 		case BOARD_NCR5380:
 			flags = FLAG_NO_PSEUDO_DMA;
 			break;
 		case BOARD_NCR53C400:
+#ifdef PSEUDO_DMA
 			flags = FLAG_NCR53C400;
+#else
+			flags = FLAG_NO_PSEUDO_DMA;
+#endif
 			break;
 		case BOARD_NCR53C400A:
 			flags = FLAG_NO_PSEUDO_DMA;
@@ -415,6 +418,13 @@ static int __init generic_NCR5380_detect
 #ifndef SCSI_G_NCR5380_MEM
 		instance->io_port = overrides[current_override].NCR5380_map_name;
 		instance->n_io_port = region_size;
+
+		/*
+		 * On NCR53C400 boards, NCR5380 registers are mapped 8 past
+		 * the base address.
+		 */
+		if (overrides[current_override].board == BOARD_NCR53C400)
+			instance->io_port += 8;
 #else
 		instance->base = overrides[current_override].NCR5380_map_name;
 		((struct NCR5380_hostdata *)instance->hostdata)->iomem = iomem;
@@ -422,6 +432,9 @@ static int __init generic_NCR5380_detect
 
 		NCR5380_init(instance, flags);
 
+		if (overrides[current_override].board == BOARD_NCR53C400)
+			NCR5380_write(C400_CONTROL_STATUS_REG, CSR_BASE);
+
 		NCR5380_maybe_reset_bus(instance);
 
 		if (overrides[current_override].irq != IRQ_AUTO)
@@ -506,7 +519,7 @@ generic_NCR5380_biosparam(struct scsi_de
 }
 #endif
 
-#ifdef NCR53C400_PSEUDO_DMA
+#ifdef PSEUDO_DMA
 
 /**
  *	NCR5380_pread		-	pseudo DMA read
@@ -690,7 +703,7 @@ static inline int NCR5380_pwrite(struct
 		; 	// TIMEOUT
 	return 0;
 }
-#endif				/* PSEUDO_DMA */
+#endif /* PSEUDO_DMA */
 
 /*
  *	Include the NCR5380 core code that we build our driver around	
Index: linux/drivers/scsi/g_NCR5380.h
===================================================================
--- linux.orig/drivers/scsi/g_NCR5380.h	2015-11-18 19:33:09.000000000 +1100
+++ linux/drivers/scsi/g_NCR5380.h	2015-11-18 19:33:12.000000000 +1100
@@ -14,7 +14,7 @@
 #ifndef GENERIC_NCR5380_H
 #define GENERIC_NCR5380_H
 
-#ifdef NCR53C400
+#ifdef CONFIG_SCSI_GENERIC_NCR53C400
 #define BIOSPARAM
 #define NCR5380_BIOSPARAM generic_NCR5380_biosparam
 #else
@@ -37,9 +37,8 @@
 #define NCR5380_map_type int
 #define NCR5380_map_name port
 #define NCR53C400_register_offset 0
-#define NCR53C400_address_adjust 8
 
-#ifdef NCR53C400
+#ifdef CONFIG_SCSI_GENERIC_NCR53C400
 #define NCR5380_region_size 16
 #else
 #define NCR5380_region_size 8
@@ -58,7 +57,6 @@
 #define NCR5380_map_type unsigned long
 #define NCR5380_map_name base
 #define NCR53C400_register_offset 0x108
-#define NCR53C400_address_adjust 0
 #define NCR53C400_mem_base 0x3880
 #define NCR53C400_host_buffer 0x3900
 #define NCR5380_region_size 0x3a00

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

* [PATCH 09/71] atari_NCR5380: Reset bus on driver initialization if required
  2015-11-18  8:34 ` Finn Thain
@ 2015-11-18  8:35   ` Finn Thain
  -1 siblings, 0 replies; 268+ messages in thread
From: Finn Thain @ 2015-11-18  8:35 UTC (permalink / raw)
  To: James E.J. Bottomley, Michael Schmitz, linux-m68k, linux-scsi,
	linux-kernel

[-- Attachment #1: atari_NCR5380-merge-do_reset --]
[-- Type: text/plain, Size: 6998 bytes --]

Merge the bus reset code from NCR5380.c into atari_NCR5380.c. This allows
for removal of a lot of duplicated code conditional on the RESET_BOOT
macro (in the next patch).

The atari_NCR5380.c fork lacks the do_reset() and NCR5380_poll_politely()
routines from NCR5380.c, so introduce them. They are indispensible. Keep
the two implementations in sync.

Signed-off-by: Finn Thain <fthain@telegraphics.com.au>

---
 drivers/scsi/NCR5380.c       |   33 +++++++-----
 drivers/scsi/atari_NCR5380.c |  113 +++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 134 insertions(+), 12 deletions(-)

Index: linux/drivers/scsi/NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/NCR5380.c	2015-11-18 19:33:12.000000000 +1100
+++ linux/drivers/scsi/NCR5380.c	2015-11-18 19:33:13.000000000 +1100
@@ -838,19 +838,20 @@ static int NCR5380_maybe_reset_bus(struc
 		case 1:
 		case 3:
 		case 5:
-			printk(KERN_INFO "scsi%d: SCSI bus busy, waiting up to five seconds\n", instance->host_no);
-			NCR5380_poll_politely(instance, STATUS_REG, SR_BSY, 0, 5*HZ);
+			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:
-			printk(KERN_WARNING "scsi%d: bus busy, attempting abort\n", instance->host_no);
+			shost_printk(KERN_ERR, instance, "bus busy, attempting abort\n");
 			do_abort(instance);
 			break;
 		case 4:
-			printk(KERN_WARNING "scsi%d: bus busy, attempting reset\n", instance->host_no);
+			shost_printk(KERN_ERR, instance, "bus busy, attempting reset\n");
 			do_reset(instance);
 			break;
 		case 6:
-			printk(KERN_ERR "scsi%d: bus locked solid or invalid override\n", instance->host_no);
+			shost_printk(KERN_ERR, instance, "bus locked solid\n");
 			return -ENXIO;
 		}
 	}
@@ -1579,21 +1580,29 @@ static int NCR5380_transfer_pio(struct S
 }
 
 /**
- *	do_reset	-	issue a reset command
- *	@host: adapter to reset
+ * 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.
+ * Issue a reset sequence to the NCR5380 and try and get the bus
+ * back into sane shape.
  *
- *	Locks: caller holds queue lock
+ * 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)
 {
-	NCR5380_write(TARGET_COMMAND_REG, PHASE_SR_TO_TCR(NCR5380_read(STATUS_REG) & PHASE_MASK));
+	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(25);
+	udelay(50);
 	NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
+	(void)NCR5380_read(RESET_PARITY_INTERRUPT_REG);
+	local_irq_restore(flags);
 }
 
 /*
Index: linux/drivers/scsi/atari_NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/atari_NCR5380.c	2015-11-18 19:25:56.000000000 +1100
+++ linux/drivers/scsi/atari_NCR5380.c	2015-11-18 19:33:13.000000000 +1100
@@ -234,6 +234,9 @@
 #define	HOSTNO		instance->host_no
 #define	H_NO(cmd)	(cmd)->device->host->host_no
 
+static int do_abort(struct Scsi_Host *);
+static void do_reset(struct Scsi_Host *);
+
 #ifdef SUPPORT_TAGS
 
 /*
@@ -475,6 +478,47 @@ static inline void initialize_SCp(struct
 	}
 }
 
+/**
+ * NCR5380_poll_politely - wait for NCR5380 status bits
+ * @instance: controller to poll
+ * @reg: 5380 register to poll
+ * @bit: Bitmask to check
+ * @val: Value required to exit
+ *
+ * Polls the NCR5380 in a reasonably efficient manner waiting for
+ * an event to occur, after a short quick poll we begin giving the
+ * CPU back in non IRQ contexts
+ *
+ * Returns the value of the register or a negative error code.
+ */
+
+static int NCR5380_poll_politely(struct Scsi_Host *instance,
+                                 int reg, int bit, int val, int t)
+{
+	int n = 500;
+	unsigned long end = jiffies + t;
+	int r;
+
+	while (n-- > 0) {
+		r = NCR5380_read(reg);
+		if ((r & bit) == val)
+			return 0;
+		cpu_relax();
+	}
+
+	/* t time yet ? */
+	while (time_before(jiffies, end)) {
+		r = NCR5380_read(reg);
+		if ((r & bit) == val)
+			return 0;
+		if (!in_interrupt())
+			cond_resched();
+		else
+			cpu_relax();
+	}
+	return -ETIMEDOUT;
+}
+
 #include <linux/delay.h>
 
 #if NDEBUG
@@ -801,6 +845,49 @@ static int __init NCR5380_init(struct Sc
 }
 
 /**
+ * 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)
+{
+	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);
+			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
  *
@@ -1741,6 +1828,32 @@ static int NCR5380_transfer_pio(struct S
 		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);
+}
+
 /*
  * Function : do_abort (Scsi_Host *host)
  *



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

* [PATCH 09/71] atari_NCR5380: Reset bus on driver initialization if required
@ 2015-11-18  8:35   ` Finn Thain
  0 siblings, 0 replies; 268+ messages in thread
From: Finn Thain @ 2015-11-18  8:35 UTC (permalink / raw)
  To: James E.J. Bottomley, Michael Schmitz, linux-m68k, linux-scsi,
	linux-kernel

[-- Attachment #1: atari_NCR5380-merge-do_reset --]
[-- Type: text/plain, Size: 6996 bytes --]

Merge the bus reset code from NCR5380.c into atari_NCR5380.c. This allows
for removal of a lot of duplicated code conditional on the RESET_BOOT
macro (in the next patch).

The atari_NCR5380.c fork lacks the do_reset() and NCR5380_poll_politely()
routines from NCR5380.c, so introduce them. They are indispensible. Keep
the two implementations in sync.

Signed-off-by: Finn Thain <fthain@telegraphics.com.au>

---
 drivers/scsi/NCR5380.c       |   33 +++++++-----
 drivers/scsi/atari_NCR5380.c |  113 +++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 134 insertions(+), 12 deletions(-)

Index: linux/drivers/scsi/NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/NCR5380.c	2015-11-18 19:33:12.000000000 +1100
+++ linux/drivers/scsi/NCR5380.c	2015-11-18 19:33:13.000000000 +1100
@@ -838,19 +838,20 @@ static int NCR5380_maybe_reset_bus(struc
 		case 1:
 		case 3:
 		case 5:
-			printk(KERN_INFO "scsi%d: SCSI bus busy, waiting up to five seconds\n", instance->host_no);
-			NCR5380_poll_politely(instance, STATUS_REG, SR_BSY, 0, 5*HZ);
+			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:
-			printk(KERN_WARNING "scsi%d: bus busy, attempting abort\n", instance->host_no);
+			shost_printk(KERN_ERR, instance, "bus busy, attempting abort\n");
 			do_abort(instance);
 			break;
 		case 4:
-			printk(KERN_WARNING "scsi%d: bus busy, attempting reset\n", instance->host_no);
+			shost_printk(KERN_ERR, instance, "bus busy, attempting reset\n");
 			do_reset(instance);
 			break;
 		case 6:
-			printk(KERN_ERR "scsi%d: bus locked solid or invalid override\n", instance->host_no);
+			shost_printk(KERN_ERR, instance, "bus locked solid\n");
 			return -ENXIO;
 		}
 	}
@@ -1579,21 +1580,29 @@ static int NCR5380_transfer_pio(struct S
 }
 
 /**
- *	do_reset	-	issue a reset command
- *	@host: adapter to reset
+ * 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.
+ * Issue a reset sequence to the NCR5380 and try and get the bus
+ * back into sane shape.
  *
- *	Locks: caller holds queue lock
+ * 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)
 {
-	NCR5380_write(TARGET_COMMAND_REG, PHASE_SR_TO_TCR(NCR5380_read(STATUS_REG) & PHASE_MASK));
+	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(25);
+	udelay(50);
 	NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
+	(void)NCR5380_read(RESET_PARITY_INTERRUPT_REG);
+	local_irq_restore(flags);
 }
 
 /*
Index: linux/drivers/scsi/atari_NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/atari_NCR5380.c	2015-11-18 19:25:56.000000000 +1100
+++ linux/drivers/scsi/atari_NCR5380.c	2015-11-18 19:33:13.000000000 +1100
@@ -234,6 +234,9 @@
 #define	HOSTNO		instance->host_no
 #define	H_NO(cmd)	(cmd)->device->host->host_no
 
+static int do_abort(struct Scsi_Host *);
+static void do_reset(struct Scsi_Host *);
+
 #ifdef SUPPORT_TAGS
 
 /*
@@ -475,6 +478,47 @@ static inline void initialize_SCp(struct
 	}
 }
 
+/**
+ * NCR5380_poll_politely - wait for NCR5380 status bits
+ * @instance: controller to poll
+ * @reg: 5380 register to poll
+ * @bit: Bitmask to check
+ * @val: Value required to exit
+ *
+ * Polls the NCR5380 in a reasonably efficient manner waiting for
+ * an event to occur, after a short quick poll we begin giving the
+ * CPU back in non IRQ contexts
+ *
+ * Returns the value of the register or a negative error code.
+ */
+
+static int NCR5380_poll_politely(struct Scsi_Host *instance,
+                                 int reg, int bit, int val, int t)
+{
+	int n = 500;
+	unsigned long end = jiffies + t;
+	int r;
+
+	while (n-- > 0) {
+		r = NCR5380_read(reg);
+		if ((r & bit) == val)
+			return 0;
+		cpu_relax();
+	}
+
+	/* t time yet ? */
+	while (time_before(jiffies, end)) {
+		r = NCR5380_read(reg);
+		if ((r & bit) == val)
+			return 0;
+		if (!in_interrupt())
+			cond_resched();
+		else
+			cpu_relax();
+	}
+	return -ETIMEDOUT;
+}
+
 #include <linux/delay.h>
 
 #if NDEBUG
@@ -801,6 +845,49 @@ static int __init NCR5380_init(struct Sc
 }
 
 /**
+ * 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)
+{
+	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);
+			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
  *
@@ -1741,6 +1828,32 @@ static int NCR5380_transfer_pio(struct S
 		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);
+}
+
 /*
  * Function : do_abort (Scsi_Host *host)
  *

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

* [PATCH 10/71] atari_NCR5380: Remove RESET_BOOT, CONFIG_ATARI_SCSI_TOSHIBA_DELAY and CONFIG_ATARI_SCSI_RESET_BOOT
  2015-11-18  8:34 ` Finn Thain
@ 2015-11-18  8:35   ` Finn Thain
  -1 siblings, 0 replies; 268+ messages in thread
From: Finn Thain @ 2015-11-18  8:35 UTC (permalink / raw)
  To: James E.J. Bottomley, Michael Schmitz, linux-m68k, linux-scsi,
	linux-kernel

[-- Attachment #1: atari_NCR5380-remove-RESET_BOOT --]
[-- Type: text/plain, Size: 16555 bytes --]

The atari_NCR5380.c core driver now takes care of bus reset upon driver
initialization if required (same as NCR5380.c). Move the Toshiba CD-ROM
support into the core driver, enabled with a host flag, so that all
NCR5380 drivers can make use of it.

Drop the RESET_BOOT macros and the ATARI_SCSI_RESET_BOOT and 
ATARI_SCSI_TOSHIBA_DELAY Kconfig symbols, which are now redundant.

Remove the atari_scsi_reset_boot(), mac_scsi_reset_boot() and
sun3_scsi_reset_boot() routines. None of this duplicated code is needed
now that all drivers can use NCR5380_maybe_reset_bus().

This brings atari_scsi, mac_scsi and sun3_scsi into line with all of the
other NCR5380 drivers.

The bus reset may raise an interrupt. That would be new behaviour for
atari_scsi only when CONFIG_ATARI_SCSI_RESET_BOOT=n. The ST DMA interrupt
is not assigned to atari_scsi at this stage, so
CONFIG_ATARI_SCSI_RESET_BOOT=y may well be problematic already.
Regardless, do_reset() now raises and clears the interrupt within
local_irq_save/restore which should avoid problems.

Signed-off-by: Finn Thain <fthain@telegraphics.com.au>

---
 drivers/scsi/Kconfig         |   17 -----------
 drivers/scsi/NCR5380.c       |   17 +++++++++--
 drivers/scsi/NCR5380.h       |    1 
 drivers/scsi/atari_NCR5380.c |   22 +++++++++-----
 drivers/scsi/atari_scsi.c    |   60 +++++----------------------------------
 drivers/scsi/mac_scsi.c      |   65 ++++++-------------------------------------
 drivers/scsi/sun3_scsi.c     |   47 -------------------------------
 7 files changed, 51 insertions(+), 178 deletions(-)

Index: linux/drivers/scsi/Kconfig
===================================================================
--- linux.orig/drivers/scsi/Kconfig	2015-11-18 19:25:56.000000000 +1100
+++ linux/drivers/scsi/Kconfig	2015-11-18 19:33:15.000000000 +1100
@@ -1624,23 +1624,6 @@ config ATARI_SCSI
 	  ST-DMA, replacing ACSI).  It does NOT support other schemes, like
 	  in the Hades (without DMA).
 
-config ATARI_SCSI_TOSHIBA_DELAY
-	bool "Long delays for Toshiba CD-ROMs"
-	depends on ATARI_SCSI
-	help
-	  This option increases the delay after a SCSI arbitration to
-	  accommodate some flaky Toshiba CD-ROM drives. Say Y if you intend to
-	  use a Toshiba CD-ROM drive; otherwise, the option is not needed and
-	  would impact performance a bit, so say N.
-
-config ATARI_SCSI_RESET_BOOT
-	bool "Reset SCSI-devices at boottime"
-	depends on ATARI_SCSI
-	help
-	  Reset the devices on your Atari whenever it boots.  This makes the
-	  boot process fractionally longer but may assist recovery from errors
-	  that leave the devices with SCSI operations partway completed.
-
 config MAC_SCSI
 	tristate "Macintosh NCR5380 SCSI"
 	depends on MAC && SCSI=y
Index: linux/drivers/scsi/atari_NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/atari_NCR5380.c	2015-11-18 19:33:13.000000000 +1100
+++ linux/drivers/scsi/atari_NCR5380.c	2015-11-18 19:33:15.000000000 +1100
@@ -674,13 +674,14 @@ static void prepare_info(struct Scsi_Hos
 	         "base 0x%lx, irq %d, "
 	         "can_queue %d, cmd_per_lun %d, "
 	         "sg_tablesize %d, this_id %d, "
-	         "flags { %s}, "
+	         "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
@@ -860,6 +861,7 @@ static int __init NCR5380_init(struct Sc
 
 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) {
@@ -878,6 +880,14 @@ static int NCR5380_maybe_reset_bus(struc
 		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");
@@ -1493,12 +1503,10 @@ static int NCR5380_select(struct Scsi_Ho
 	 * a minimum so we'll udelay ceil(1.2)
 	 */
 
-#ifdef CONFIG_ATARI_SCSI_TOSHIBA_DELAY
-	/* ++roman: But some targets (see above :-) seem to need a bit more... */
-	udelay(15);
-#else
-	udelay(2);
-#endif
+	if (hostdata->flags & FLAG_TOSHIBA_DELAY)
+		udelay(15);
+	else
+		udelay(2);
 
 	if (hostdata->connected) {
 		NCR5380_write(MODE_REG, MR_BASE);
Index: linux/drivers/scsi/atari_scsi.c
===================================================================
--- linux.orig/drivers/scsi/atari_scsi.c	2015-11-18 19:32:58.000000000 +1100
+++ linux/drivers/scsi/atari_scsi.c	2015-11-18 19:33:15.000000000 +1100
@@ -164,15 +164,6 @@ static inline unsigned long SCSI_DMA_GET
 #define HOSTDATA_DMALEN		(((struct NCR5380_hostdata *) \
 				(atari_scsi_host->hostdata))->dma_len)
 
-/* Time (in jiffies) to wait after a reset; the SCSI standard calls for 250ms,
- * we usually do 0.5s to be on the safe side. But Toshiba CD-ROMs once more
- * need ten times the standard value... */
-#ifndef CONFIG_ATARI_SCSI_TOSHIBA_DELAY
-#define	AFTER_RESET_DELAY	(HZ/2)
-#else
-#define	AFTER_RESET_DELAY	(5*HZ/2)
-#endif
-
 #ifdef REAL_DMA
 static void atari_scsi_fetch_restbytes(void);
 #endif
@@ -208,12 +199,12 @@ 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);
+static int setup_toshiba_delay = -1;
+module_param(setup_toshiba_delay, int, 0);
 
 
 #if defined(REAL_DMA)
@@ -488,7 +479,7 @@ static int __init atari_scsi_setup(char
 	 * Defaults depend on TT or Falcon, determined at run time.
 	 * Negative values mean don't change.
 	 */
-	int ints[6];
+	int ints[8];
 
 	get_options(str, ARRAY_SIZE(ints), ints);
 
@@ -504,10 +495,11 @@ static int __init atari_scsi_setup(char
 		setup_sg_tablesize = ints[3];
 	if (ints[0] >= 4)
 		setup_hostid = ints[4];
-#ifdef SUPPORT_TAGS
 	if (ints[0] >= 5)
 		setup_use_tagged_queuing = ints[5];
-#endif
+	/* ints[6] (use_pdma) is ignored */
+	if (ints[0] >= 7)
+		setup_toshiba_delay = ints[7];
 
 	return 1;
 }
@@ -516,38 +508,6 @@ __setup("atascsi=", atari_scsi_setup);
 #endif /* !MODULE */
 
 
-#ifdef CONFIG_ATARI_SCSI_RESET_BOOT
-static void __init atari_scsi_reset_boot(void)
-{
-	unsigned long end;
-
-	/*
-	 * Do a SCSI reset to clean up the bus during initialization. No messing
-	 * with the queues, interrupts, or locks necessary here.
-	 */
-
-	printk("Atari SCSI: resetting the SCSI bus...");
-
-	/* get in phase */
-	NCR5380_write(TARGET_COMMAND_REG,
-		      PHASE_SR_TO_TCR(NCR5380_read(STATUS_REG)));
-
-	/* assert RST */
-	NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_RST);
-	/* The min. reset hold time is 25us, so 40us should be enough */
-	udelay(50);
-	/* reset RST and interrupt */
-	NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
-	NCR5380_read(RESET_PARITY_INTERRUPT_REG);
-
-	end = jiffies + AFTER_RESET_DELAY;
-	while (time_before(jiffies, end))
-		barrier();
-
-	printk(" done\n");
-}
-#endif
-
 #if defined(REAL_DMA)
 
 static unsigned long atari_scsi_dma_setup(struct Scsi_Host *instance,
@@ -917,17 +877,13 @@ static int __init atari_scsi_probe(struc
 	}
 	atari_scsi_host = instance;
 
-#ifdef CONFIG_ATARI_SCSI_RESET_BOOT
-	atari_scsi_reset_boot();
-#endif
-
 	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;
 
 	NCR5380_init(instance, host_flags);
 
@@ -975,6 +931,8 @@ static int __init atari_scsi_probe(struc
 #endif
 	}
 
+	NCR5380_maybe_reset_bus(instance);
+
 	error = scsi_add_host(instance, NULL);
 	if (error)
 		goto fail_host;
Index: linux/drivers/scsi/mac_scsi.c
===================================================================
--- linux.orig/drivers/scsi/mac_scsi.c	2015-11-18 19:33:05.000000000 +1100
+++ linux/drivers/scsi/mac_scsi.c	2015-11-18 19:33:15.000000000 +1100
@@ -49,8 +49,6 @@
 
 #include "NCR5380.h"
 
-#define RESET_BOOT
-
 static int setup_can_queue = -1;
 module_param(setup_can_queue, int, 0);
 static int setup_cmd_per_lun = -1;
@@ -63,17 +61,8 @@ 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);
-
-/* Time (in jiffies) to wait after a reset; the SCSI standard calls for 250ms,
- * we usually do 0.5s to be on the safe side. But Toshiba CD-ROMs once more
- * need ten times the standard value... */
-#define TOSHIBA_DELAY
-
-#ifdef TOSHIBA_DELAY
-#define	AFTER_RESET_DELAY	(5*HZ/2)
-#else
-#define	AFTER_RESET_DELAY	(HZ/2)
-#endif
+static int setup_toshiba_delay = -1;
+module_param(setup_toshiba_delay, int, 0);
 
 /*
  * NCR 5380 register access functions
@@ -92,12 +81,12 @@ static inline void macscsi_write(struct
 #ifndef MODULE
 static int __init mac_scsi_setup(char *str)
 {
-	int ints[7];
+	int ints[8];
 
 	(void)get_options(str, ARRAY_SIZE(ints), ints);
 
-	if (ints[0] < 1 || ints[0] > 6) {
-		pr_err("Usage: mac5380=<can_queue>[,<cmd_per_lun>[,<sg_tablesize>[,<hostid>[,<use_tags>[,<use_pdma>]]]]]\n");
+	if (ints[0] < 1) {
+		pr_err("Usage: mac5380=<can_queue>[,<cmd_per_lun>[,<sg_tablesize>[,<hostid>[,<use_tags>[,<use_pdma>[,toshiba_delay]]]]]]\n");
 		return 0;
 	}
 	if (ints[0] >= 1)
@@ -112,47 +101,14 @@ static int __init mac_scsi_setup(char *s
 		setup_use_tagged_queuing = ints[5];
 	if (ints[0] >= 6)
 		setup_use_pdma = ints[6];
+	if (ints[0] >= 7)
+		setup_toshiba_delay = ints[7];
 	return 1;
 }
 
 __setup("mac5380=", mac_scsi_setup);
 #endif /* !MODULE */
 
-#ifdef RESET_BOOT
-/*
- * Our 'bus reset on boot' function
- */
-
-static void mac_scsi_reset_boot(struct Scsi_Host *instance)
-{
-	unsigned long end;
-
-	/*
-	 * Do a SCSI reset to clean up the bus during initialization. No messing
-	 * with the queues, interrupts, or locks necessary here.
-	 */
-
-	printk(KERN_INFO "Macintosh SCSI: resetting the SCSI bus..." );
-
-	/* get in phase */
-	NCR5380_write( TARGET_COMMAND_REG,
-		      PHASE_SR_TO_TCR( NCR5380_read(STATUS_REG) ));
-
-	/* assert RST */
-	NCR5380_write( INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_RST );
-	/* The min. reset hold time is 25us, so 40us should be enough */
-	udelay( 50 );
-	/* reset RST and interrupt */
-	NCR5380_write( INITIATOR_COMMAND_REG, ICR_BASE );
-	NCR5380_read( RESET_PARITY_INTERRUPT_REG );
-
-	for( end = jiffies + AFTER_RESET_DELAY; time_before(jiffies, end); )
-		barrier();
-
-	printk(KERN_INFO " done\n" );
-}
-#endif
-
 #ifdef PSEUDO_DMA
 /* 
    Pseudo-DMA: (Ove Edlund)
@@ -421,13 +377,10 @@ static int __init mac_scsi_probe(struct
 	} else
 		host_flags |= FLAG_NO_PSEUDO_DMA;
 
-#ifdef RESET_BOOT
-	mac_scsi_reset_boot(instance);
-#endif
-
 #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;
 
 	NCR5380_init(instance, host_flags);
 
@@ -438,6 +391,8 @@ static int __init mac_scsi_probe(struct
 			goto fail_irq;
 	}
 
+	NCR5380_maybe_reset_bus(instance);
+
 	error = scsi_add_host(instance, NULL);
 	if (error)
 		goto fail_host;
Index: linux/drivers/scsi/sun3_scsi.c
===================================================================
--- linux.orig/drivers/scsi/sun3_scsi.c	2015-11-18 19:32:59.000000000 +1100
+++ linux/drivers/scsi/sun3_scsi.c	2015-11-18 19:33:15.000000000 +1100
@@ -86,10 +86,6 @@ module_param(setup_use_tagged_queuing, i
 static int setup_hostid = -1;
 module_param(setup_hostid, int, 0);
 
-/* #define RESET_BOOT */
-
-#define	AFTER_RESET_DELAY	(HZ/2)
-
 /* ms to wait after hitting dma regs */
 #define SUN3_DMA_DELAY 10
 
@@ -144,45 +140,6 @@ static inline void sun3_udc_write(unsign
 }
 #endif
 
-#ifdef RESET_BOOT
-static void sun3_scsi_reset_boot(struct Scsi_Host *instance)
-{
-	unsigned long end;
-	
-	/*
-	 * Do a SCSI reset to clean up the bus during initialization. No
-	 * messing with the queues, interrupts, or locks necessary here.
-	 */
-
-	printk( "Sun3 SCSI: resetting the SCSI bus..." );
-
-	/* switch off SCSI IRQ - catch an interrupt without IRQ bit set else */
-//       	sun3_disable_irq( IRQ_SUN3_SCSI );
-
-	/* get in phase */
-	NCR5380_write( TARGET_COMMAND_REG,
-		      PHASE_SR_TO_TCR( NCR5380_read(STATUS_REG) ));
-
-	/* assert RST */
-	NCR5380_write( INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_RST );
-
-	/* The min. reset hold time is 25us, so 40us should be enough */
-	udelay( 50 );
-
-	/* reset RST and interrupt */
-	NCR5380_write( INITIATOR_COMMAND_REG, ICR_BASE );
-	NCR5380_read( RESET_PARITY_INTERRUPT_REG );
-
-	for( end = jiffies + AFTER_RESET_DELAY; time_before(jiffies, end); )
-		barrier();
-
-	/* switch on SCSI IRQ again */
-//       	sun3_enable_irq( IRQ_SUN3_SCSI );
-
-	printk( " done\n" );
-}
-#endif
-
 // safe bits for the CSR
 #define CSR_GOOD 0x060f
 
@@ -631,9 +588,7 @@ static int __init sun3_scsi_probe(struct
 	dregs->ivect = VME_DATA24 | (instance->irq & 0xff);
 #endif
 
-#ifdef RESET_BOOT
-	sun3_scsi_reset_boot(instance);
-#endif
+	NCR5380_maybe_reset_bus(instance);
 
 	error = scsi_add_host(instance, NULL);
 	if (error)
Index: linux/drivers/scsi/NCR5380.h
===================================================================
--- linux.orig/drivers/scsi/NCR5380.h	2015-11-18 19:33:10.000000000 +1100
+++ linux/drivers/scsi/NCR5380.h	2015-11-18 19:33:15.000000000 +1100
@@ -243,6 +243,7 @@
 #define FLAG_DTC3181E			16	/* DTC3181E */
 #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 {
Index: linux/drivers/scsi/NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/NCR5380.c	2015-11-18 19:33:13.000000000 +1100
+++ linux/drivers/scsi/NCR5380.c	2015-11-18 19:33:15.000000000 +1100
@@ -618,7 +618,7 @@ static void prepare_info(struct Scsi_Hos
 	         "base 0x%lx, irq %d, "
 	         "can_queue %d, cmd_per_lun %d, "
 	         "sg_tablesize %d, this_id %d, "
-	         "flags { %s%s%s}, "
+	         "flags { %s%s%s%s}, "
 #if defined(USLEEP_POLL) && defined(USLEEP_WAITLONG)
 		 "USLEEP_POLL %lu, USLEEP_WAITLONG %lu, "
 #endif
@@ -630,6 +630,7 @@ static void prepare_info(struct Scsi_Hos
 	         hostdata->flags & FLAG_NCR53C400     ? "NCR53C400 "     : "",
 	         hostdata->flags & FLAG_DTC3181E      ? "DTC3181E "      : "",
 	         hostdata->flags & FLAG_NO_PSEUDO_DMA ? "NO_PSEUDO_DMA " : "",
+	         hostdata->flags & FLAG_TOSHIBA_DELAY ? "TOSHIBA_DELAY "  : "",
 #if defined(USLEEP_POLL) && defined(USLEEP_WAITLONG)
 	         USLEEP_POLL, USLEEP_WAITLONG,
 #endif
@@ -831,6 +832,7 @@ static int NCR5380_init(struct Scsi_Host
 
 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) {
@@ -849,6 +851,14 @@ static int NCR5380_maybe_reset_bus(struc
 		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");
@@ -1253,7 +1263,10 @@ static int NCR5380_select(struct Scsi_Ho
 	 * a minimum so we'll udelay ceil(1.2)
 	 */
 
-	udelay(2);
+	if (hostdata->flags & FLAG_TOSHIBA_DELAY)
+		udelay(15);
+	else
+		udelay(2);
 
 	dprintk(NDEBUG_ARBITRATION, "scsi%d : won arbitration\n", instance->host_no);
 



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

* [PATCH 10/71] atari_NCR5380: Remove RESET_BOOT, CONFIG_ATARI_SCSI_TOSHIBA_DELAY and CONFIG_ATARI_SCSI_RESET_BOOT
@ 2015-11-18  8:35   ` Finn Thain
  0 siblings, 0 replies; 268+ messages in thread
From: Finn Thain @ 2015-11-18  8:35 UTC (permalink / raw)
  To: James E.J. Bottomley, Michael Schmitz, linux-m68k, linux-scsi,
	linux-kernel

[-- Attachment #1: atari_NCR5380-remove-RESET_BOOT --]
[-- Type: text/plain, Size: 16555 bytes --]

The atari_NCR5380.c core driver now takes care of bus reset upon driver
initialization if required (same as NCR5380.c). Move the Toshiba CD-ROM
support into the core driver, enabled with a host flag, so that all
NCR5380 drivers can make use of it.

Drop the RESET_BOOT macros and the ATARI_SCSI_RESET_BOOT and 
ATARI_SCSI_TOSHIBA_DELAY Kconfig symbols, which are now redundant.

Remove the atari_scsi_reset_boot(), mac_scsi_reset_boot() and
sun3_scsi_reset_boot() routines. None of this duplicated code is needed
now that all drivers can use NCR5380_maybe_reset_bus().

This brings atari_scsi, mac_scsi and sun3_scsi into line with all of the
other NCR5380 drivers.

The bus reset may raise an interrupt. That would be new behaviour for
atari_scsi only when CONFIG_ATARI_SCSI_RESET_BOOT=n. The ST DMA interrupt
is not assigned to atari_scsi at this stage, so
CONFIG_ATARI_SCSI_RESET_BOOT=y may well be problematic already.
Regardless, do_reset() now raises and clears the interrupt within
local_irq_save/restore which should avoid problems.

Signed-off-by: Finn Thain <fthain@telegraphics.com.au>

---
 drivers/scsi/Kconfig         |   17 -----------
 drivers/scsi/NCR5380.c       |   17 +++++++++--
 drivers/scsi/NCR5380.h       |    1 
 drivers/scsi/atari_NCR5380.c |   22 +++++++++-----
 drivers/scsi/atari_scsi.c    |   60 +++++----------------------------------
 drivers/scsi/mac_scsi.c      |   65 ++++++-------------------------------------
 drivers/scsi/sun3_scsi.c     |   47 -------------------------------
 7 files changed, 51 insertions(+), 178 deletions(-)

Index: linux/drivers/scsi/Kconfig
===================================================================
--- linux.orig/drivers/scsi/Kconfig	2015-11-18 19:25:56.000000000 +1100
+++ linux/drivers/scsi/Kconfig	2015-11-18 19:33:15.000000000 +1100
@@ -1624,23 +1624,6 @@ config ATARI_SCSI
 	  ST-DMA, replacing ACSI).  It does NOT support other schemes, like
 	  in the Hades (without DMA).
 
-config ATARI_SCSI_TOSHIBA_DELAY
-	bool "Long delays for Toshiba CD-ROMs"
-	depends on ATARI_SCSI
-	help
-	  This option increases the delay after a SCSI arbitration to
-	  accommodate some flaky Toshiba CD-ROM drives. Say Y if you intend to
-	  use a Toshiba CD-ROM drive; otherwise, the option is not needed and
-	  would impact performance a bit, so say N.
-
-config ATARI_SCSI_RESET_BOOT
-	bool "Reset SCSI-devices at boottime"
-	depends on ATARI_SCSI
-	help
-	  Reset the devices on your Atari whenever it boots.  This makes the
-	  boot process fractionally longer but may assist recovery from errors
-	  that leave the devices with SCSI operations partway completed.
-
 config MAC_SCSI
 	tristate "Macintosh NCR5380 SCSI"
 	depends on MAC && SCSI=y
Index: linux/drivers/scsi/atari_NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/atari_NCR5380.c	2015-11-18 19:33:13.000000000 +1100
+++ linux/drivers/scsi/atari_NCR5380.c	2015-11-18 19:33:15.000000000 +1100
@@ -674,13 +674,14 @@ static void prepare_info(struct Scsi_Hos
 	         "base 0x%lx, irq %d, "
 	         "can_queue %d, cmd_per_lun %d, "
 	         "sg_tablesize %d, this_id %d, "
-	         "flags { %s}, "
+	         "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
@@ -860,6 +861,7 @@ static int __init NCR5380_init(struct Sc
 
 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) {
@@ -878,6 +880,14 @@ static int NCR5380_maybe_reset_bus(struc
 		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");
@@ -1493,12 +1503,10 @@ static int NCR5380_select(struct Scsi_Ho
 	 * a minimum so we'll udelay ceil(1.2)
 	 */
 
-#ifdef CONFIG_ATARI_SCSI_TOSHIBA_DELAY
-	/* ++roman: But some targets (see above :-) seem to need a bit more... */
-	udelay(15);
-#else
-	udelay(2);
-#endif
+	if (hostdata->flags & FLAG_TOSHIBA_DELAY)
+		udelay(15);
+	else
+		udelay(2);
 
 	if (hostdata->connected) {
 		NCR5380_write(MODE_REG, MR_BASE);
Index: linux/drivers/scsi/atari_scsi.c
===================================================================
--- linux.orig/drivers/scsi/atari_scsi.c	2015-11-18 19:32:58.000000000 +1100
+++ linux/drivers/scsi/atari_scsi.c	2015-11-18 19:33:15.000000000 +1100
@@ -164,15 +164,6 @@ static inline unsigned long SCSI_DMA_GET
 #define HOSTDATA_DMALEN		(((struct NCR5380_hostdata *) \
 				(atari_scsi_host->hostdata))->dma_len)
 
-/* Time (in jiffies) to wait after a reset; the SCSI standard calls for 250ms,
- * we usually do 0.5s to be on the safe side. But Toshiba CD-ROMs once more
- * need ten times the standard value... */
-#ifndef CONFIG_ATARI_SCSI_TOSHIBA_DELAY
-#define	AFTER_RESET_DELAY	(HZ/2)
-#else
-#define	AFTER_RESET_DELAY	(5*HZ/2)
-#endif
-
 #ifdef REAL_DMA
 static void atari_scsi_fetch_restbytes(void);
 #endif
@@ -208,12 +199,12 @@ 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);
+static int setup_toshiba_delay = -1;
+module_param(setup_toshiba_delay, int, 0);
 
 
 #if defined(REAL_DMA)
@@ -488,7 +479,7 @@ static int __init atari_scsi_setup(char
 	 * Defaults depend on TT or Falcon, determined at run time.
 	 * Negative values mean don't change.
 	 */
-	int ints[6];
+	int ints[8];
 
 	get_options(str, ARRAY_SIZE(ints), ints);
 
@@ -504,10 +495,11 @@ static int __init atari_scsi_setup(char
 		setup_sg_tablesize = ints[3];
 	if (ints[0] >= 4)
 		setup_hostid = ints[4];
-#ifdef SUPPORT_TAGS
 	if (ints[0] >= 5)
 		setup_use_tagged_queuing = ints[5];
-#endif
+	/* ints[6] (use_pdma) is ignored */
+	if (ints[0] >= 7)
+		setup_toshiba_delay = ints[7];
 
 	return 1;
 }
@@ -516,38 +508,6 @@ __setup("atascsi=", atari_scsi_setup);
 #endif /* !MODULE */
 
 
-#ifdef CONFIG_ATARI_SCSI_RESET_BOOT
-static void __init atari_scsi_reset_boot(void)
-{
-	unsigned long end;
-
-	/*
-	 * Do a SCSI reset to clean up the bus during initialization. No messing
-	 * with the queues, interrupts, or locks necessary here.
-	 */
-
-	printk("Atari SCSI: resetting the SCSI bus...");
-
-	/* get in phase */
-	NCR5380_write(TARGET_COMMAND_REG,
-		      PHASE_SR_TO_TCR(NCR5380_read(STATUS_REG)));
-
-	/* assert RST */
-	NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_RST);
-	/* The min. reset hold time is 25us, so 40us should be enough */
-	udelay(50);
-	/* reset RST and interrupt */
-	NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
-	NCR5380_read(RESET_PARITY_INTERRUPT_REG);
-
-	end = jiffies + AFTER_RESET_DELAY;
-	while (time_before(jiffies, end))
-		barrier();
-
-	printk(" done\n");
-}
-#endif
-
 #if defined(REAL_DMA)
 
 static unsigned long atari_scsi_dma_setup(struct Scsi_Host *instance,
@@ -917,17 +877,13 @@ static int __init atari_scsi_probe(struc
 	}
 	atari_scsi_host = instance;
 
-#ifdef CONFIG_ATARI_SCSI_RESET_BOOT
-	atari_scsi_reset_boot();
-#endif
-
 	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;
 
 	NCR5380_init(instance, host_flags);
 
@@ -975,6 +931,8 @@ static int __init atari_scsi_probe(struc
 #endif
 	}
 
+	NCR5380_maybe_reset_bus(instance);
+
 	error = scsi_add_host(instance, NULL);
 	if (error)
 		goto fail_host;
Index: linux/drivers/scsi/mac_scsi.c
===================================================================
--- linux.orig/drivers/scsi/mac_scsi.c	2015-11-18 19:33:05.000000000 +1100
+++ linux/drivers/scsi/mac_scsi.c	2015-11-18 19:33:15.000000000 +1100
@@ -49,8 +49,6 @@
 
 #include "NCR5380.h"
 
-#define RESET_BOOT
-
 static int setup_can_queue = -1;
 module_param(setup_can_queue, int, 0);
 static int setup_cmd_per_lun = -1;
@@ -63,17 +61,8 @@ 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);
-
-/* Time (in jiffies) to wait after a reset; the SCSI standard calls for 250ms,
- * we usually do 0.5s to be on the safe side. But Toshiba CD-ROMs once more
- * need ten times the standard value... */
-#define TOSHIBA_DELAY
-
-#ifdef TOSHIBA_DELAY
-#define	AFTER_RESET_DELAY	(5*HZ/2)
-#else
-#define	AFTER_RESET_DELAY	(HZ/2)
-#endif
+static int setup_toshiba_delay = -1;
+module_param(setup_toshiba_delay, int, 0);
 
 /*
  * NCR 5380 register access functions
@@ -92,12 +81,12 @@ static inline void macscsi_write(struct
 #ifndef MODULE
 static int __init mac_scsi_setup(char *str)
 {
-	int ints[7];
+	int ints[8];
 
 	(void)get_options(str, ARRAY_SIZE(ints), ints);
 
-	if (ints[0] < 1 || ints[0] > 6) {
-		pr_err("Usage: mac5380=<can_queue>[,<cmd_per_lun>[,<sg_tablesize>[,<hostid>[,<use_tags>[,<use_pdma>]]]]]\n");
+	if (ints[0] < 1) {
+		pr_err("Usage: mac5380=<can_queue>[,<cmd_per_lun>[,<sg_tablesize>[,<hostid>[,<use_tags>[,<use_pdma>[,toshiba_delay]]]]]]\n");
 		return 0;
 	}
 	if (ints[0] >= 1)
@@ -112,47 +101,14 @@ static int __init mac_scsi_setup(char *s
 		setup_use_tagged_queuing = ints[5];
 	if (ints[0] >= 6)
 		setup_use_pdma = ints[6];
+	if (ints[0] >= 7)
+		setup_toshiba_delay = ints[7];
 	return 1;
 }
 
 __setup("mac5380=", mac_scsi_setup);
 #endif /* !MODULE */
 
-#ifdef RESET_BOOT
-/*
- * Our 'bus reset on boot' function
- */
-
-static void mac_scsi_reset_boot(struct Scsi_Host *instance)
-{
-	unsigned long end;
-
-	/*
-	 * Do a SCSI reset to clean up the bus during initialization. No messing
-	 * with the queues, interrupts, or locks necessary here.
-	 */
-
-	printk(KERN_INFO "Macintosh SCSI: resetting the SCSI bus..." );
-
-	/* get in phase */
-	NCR5380_write( TARGET_COMMAND_REG,
-		      PHASE_SR_TO_TCR( NCR5380_read(STATUS_REG) ));
-
-	/* assert RST */
-	NCR5380_write( INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_RST );
-	/* The min. reset hold time is 25us, so 40us should be enough */
-	udelay( 50 );
-	/* reset RST and interrupt */
-	NCR5380_write( INITIATOR_COMMAND_REG, ICR_BASE );
-	NCR5380_read( RESET_PARITY_INTERRUPT_REG );
-
-	for( end = jiffies + AFTER_RESET_DELAY; time_before(jiffies, end); )
-		barrier();
-
-	printk(KERN_INFO " done\n" );
-}
-#endif
-
 #ifdef PSEUDO_DMA
 /* 
    Pseudo-DMA: (Ove Edlund)
@@ -421,13 +377,10 @@ static int __init mac_scsi_probe(struct
 	} else
 		host_flags |= FLAG_NO_PSEUDO_DMA;
 
-#ifdef RESET_BOOT
-	mac_scsi_reset_boot(instance);
-#endif
-
 #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;
 
 	NCR5380_init(instance, host_flags);
 
@@ -438,6 +391,8 @@ static int __init mac_scsi_probe(struct
 			goto fail_irq;
 	}
 
+	NCR5380_maybe_reset_bus(instance);
+
 	error = scsi_add_host(instance, NULL);
 	if (error)
 		goto fail_host;
Index: linux/drivers/scsi/sun3_scsi.c
===================================================================
--- linux.orig/drivers/scsi/sun3_scsi.c	2015-11-18 19:32:59.000000000 +1100
+++ linux/drivers/scsi/sun3_scsi.c	2015-11-18 19:33:15.000000000 +1100
@@ -86,10 +86,6 @@ module_param(setup_use_tagged_queuing, i
 static int setup_hostid = -1;
 module_param(setup_hostid, int, 0);
 
-/* #define RESET_BOOT */
-
-#define	AFTER_RESET_DELAY	(HZ/2)
-
 /* ms to wait after hitting dma regs */
 #define SUN3_DMA_DELAY 10
 
@@ -144,45 +140,6 @@ static inline void sun3_udc_write(unsign
 }
 #endif
 
-#ifdef RESET_BOOT
-static void sun3_scsi_reset_boot(struct Scsi_Host *instance)
-{
-	unsigned long end;
-	
-	/*
-	 * Do a SCSI reset to clean up the bus during initialization. No
-	 * messing with the queues, interrupts, or locks necessary here.
-	 */
-
-	printk( "Sun3 SCSI: resetting the SCSI bus..." );
-
-	/* switch off SCSI IRQ - catch an interrupt without IRQ bit set else */
-//       	sun3_disable_irq( IRQ_SUN3_SCSI );
-
-	/* get in phase */
-	NCR5380_write( TARGET_COMMAND_REG,
-		      PHASE_SR_TO_TCR( NCR5380_read(STATUS_REG) ));
-
-	/* assert RST */
-	NCR5380_write( INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_RST );
-
-	/* The min. reset hold time is 25us, so 40us should be enough */
-	udelay( 50 );
-
-	/* reset RST and interrupt */
-	NCR5380_write( INITIATOR_COMMAND_REG, ICR_BASE );
-	NCR5380_read( RESET_PARITY_INTERRUPT_REG );
-
-	for( end = jiffies + AFTER_RESET_DELAY; time_before(jiffies, end); )
-		barrier();
-
-	/* switch on SCSI IRQ again */
-//       	sun3_enable_irq( IRQ_SUN3_SCSI );
-
-	printk( " done\n" );
-}
-#endif
-
 // safe bits for the CSR
 #define CSR_GOOD 0x060f
 
@@ -631,9 +588,7 @@ static int __init sun3_scsi_probe(struct
 	dregs->ivect = VME_DATA24 | (instance->irq & 0xff);
 #endif
 
-#ifdef RESET_BOOT
-	sun3_scsi_reset_boot(instance);
-#endif
+	NCR5380_maybe_reset_bus(instance);
 
 	error = scsi_add_host(instance, NULL);
 	if (error)
Index: linux/drivers/scsi/NCR5380.h
===================================================================
--- linux.orig/drivers/scsi/NCR5380.h	2015-11-18 19:33:10.000000000 +1100
+++ linux/drivers/scsi/NCR5380.h	2015-11-18 19:33:15.000000000 +1100
@@ -243,6 +243,7 @@
 #define FLAG_DTC3181E			16	/* DTC3181E */
 #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 {
Index: linux/drivers/scsi/NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/NCR5380.c	2015-11-18 19:33:13.000000000 +1100
+++ linux/drivers/scsi/NCR5380.c	2015-11-18 19:33:15.000000000 +1100
@@ -618,7 +618,7 @@ static void prepare_info(struct Scsi_Hos
 	         "base 0x%lx, irq %d, "
 	         "can_queue %d, cmd_per_lun %d, "
 	         "sg_tablesize %d, this_id %d, "
-	         "flags { %s%s%s}, "
+	         "flags { %s%s%s%s}, "
 #if defined(USLEEP_POLL) && defined(USLEEP_WAITLONG)
 		 "USLEEP_POLL %lu, USLEEP_WAITLONG %lu, "
 #endif
@@ -630,6 +630,7 @@ static void prepare_info(struct Scsi_Hos
 	         hostdata->flags & FLAG_NCR53C400     ? "NCR53C400 "     : "",
 	         hostdata->flags & FLAG_DTC3181E      ? "DTC3181E "      : "",
 	         hostdata->flags & FLAG_NO_PSEUDO_DMA ? "NO_PSEUDO_DMA " : "",
+	         hostdata->flags & FLAG_TOSHIBA_DELAY ? "TOSHIBA_DELAY "  : "",
 #if defined(USLEEP_POLL) && defined(USLEEP_WAITLONG)
 	         USLEEP_POLL, USLEEP_WAITLONG,
 #endif
@@ -831,6 +832,7 @@ static int NCR5380_init(struct Scsi_Host
 
 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) {
@@ -849,6 +851,14 @@ static int NCR5380_maybe_reset_bus(struc
 		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");
@@ -1253,7 +1263,10 @@ static int NCR5380_select(struct Scsi_Ho
 	 * a minimum so we'll udelay ceil(1.2)
 	 */
 
-	udelay(2);
+	if (hostdata->flags & FLAG_TOSHIBA_DELAY)
+		udelay(15);
+	else
+		udelay(2);
 
 	dprintk(NDEBUG_ARBITRATION, "scsi%d : won arbitration\n", instance->host_no);
 



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

* [PATCH 11/71] ncr5380: Simplify bus reset handlers
  2015-11-18  8:34 ` Finn Thain
@ 2015-11-18  8:35   ` Finn Thain
  -1 siblings, 0 replies; 268+ messages in thread
From: Finn Thain @ 2015-11-18  8:35 UTC (permalink / raw)
  To: James E.J. Bottomley, Michael Schmitz, linux-m68k, linux-scsi,
	linux-kernel

[-- Attachment #1: ncr5380-cleanup-bus-reset-handler --]
[-- Type: text/plain, Size: 4073 bytes --]

Make use of do_reset() in the bus reset handler in atari_NCR5380.c. The
version in NCR5380.c already does so. Keep them in sync.

Signed-off-by: Finn Thain <fthain@telegraphics.com.au>

---

Bus reset handlers in both core drivers still have serious problems for
EH purposes. Those problems are addressed later in this series.

---
 drivers/scsi/NCR5380.c       |   20 +++++++++++---------
 drivers/scsi/atari_NCR5380.c |   30 ++++++++++++------------------
 2 files changed, 23 insertions(+), 27 deletions(-)

Index: linux/drivers/scsi/NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/NCR5380.c	2015-11-18 19:33:15.000000000 +1100
+++ linux/drivers/scsi/NCR5380.c	2015-11-18 19:33:17.000000000 +1100
@@ -668,7 +668,7 @@ static void prepare_info(struct Scsi_Hos
  *	Locks: called functions disable irqs
  */
 
-static void NCR5380_print_status(struct Scsi_Host *instance)
+static void __maybe_unused NCR5380_print_status(struct Scsi_Host *instance)
 {
 	NCR5380_dprint(NDEBUG_ANY, instance);
 	NCR5380_dprint_phase(NDEBUG_ANY, instance);
@@ -2693,24 +2693,26 @@ static int NCR5380_abort(struct scsi_cmn
 }
 
 
-/* 
- * Function : int NCR5380_bus_reset (struct scsi_cmnd *cmd)
- * 
- * Purpose : reset the SCSI bus.
- *
- * Returns : SUCCESS
+/**
+ * NCR5380_bus_reset - reset the SCSI bus
+ * @cmd: SCSI command undergoing EH
  *
- * Locks: host lock taken by caller
+ * Returns SUCCESS
  */
 
 static int NCR5380_bus_reset(struct scsi_cmnd *cmd)
 {
 	struct Scsi_Host *instance = cmd->device->host;
 
+	spin_lock_irq(instance->host_lock);
+
+#if (NDEBUG & NDEBUG_ANY)
+	scmd_printk(KERN_INFO, cmd, "performing bus reset\n");
 	NCR5380_print_status(instance);
+#endif
 
-	spin_lock_irq(instance->host_lock);
 	do_reset(instance);
+
 	spin_unlock_irq(instance->host_lock);
 
 	return SUCCESS;
Index: linux/drivers/scsi/atari_NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/atari_NCR5380.c	2015-11-18 19:33:15.000000000 +1100
+++ linux/drivers/scsi/atari_NCR5380.c	2015-11-18 19:33:17.000000000 +1100
@@ -719,7 +719,7 @@ static void lprint_Scsi_Cmnd(struct scsi
 	printk("\n");
 }
 
-static void NCR5380_print_status(struct Scsi_Host *instance)
+static void __maybe_unused NCR5380_print_status(struct Scsi_Host *instance)
 {
 	struct NCR5380_hostdata *hostdata;
 	struct scsi_cmnd *ptr;
@@ -2982,13 +2982,11 @@ int NCR5380_abort(struct scsi_cmnd *cmd)
 }
 
 
-/*
- * Function : int NCR5380_reset (struct scsi_cmnd *cmd)
- *
- * Purpose : reset the SCSI bus.
- *
- * Returns : SUCCESS or FAILURE
+/**
+ * NCR5380_bus_reset - reset the SCSI bus
+ * @cmd: SCSI command undergoing EH
  *
+ * Returns SUCCESS
  */
 
 static int NCR5380_bus_reset(struct scsi_cmnd *cmd)
@@ -2998,22 +2996,19 @@ static int NCR5380_bus_reset(struct scsi
 	int i;
 	unsigned long flags;
 
+	local_irq_save(flags);
+
+#if (NDEBUG & NDEBUG_ANY)
+	scmd_printk(KERN_INFO, cmd, "performing bus reset\n");
 	NCR5380_print_status(instance);
+#endif
+
+	do_reset(instance);
 
-	/* get in phase */
-	NCR5380_write(TARGET_COMMAND_REG,
-		      PHASE_SR_TO_TCR(NCR5380_read(STATUS_REG)));
-	/* assert RST */
-	NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_RST);
-	udelay(40);
 	/* reset NCR registers */
-	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);
-	/* ++roman: reset interrupt condition! otherwise no interrupts don't get
-	 * through anymore ... */
-	(void)NCR5380_read(RESET_PARITY_INTERRUPT_REG);
 
 	/* After the reset, there are no more connected or disconnected commands
 	 * and no busy units; so clear the low-level status here to avoid
@@ -3028,7 +3023,6 @@ static int NCR5380_bus_reset(struct scsi
 	if (hostdata->disconnected_queue)
 		dprintk(NDEBUG_ABORT, "scsi%d: reset aborted disconnected command(s)\n", H_NO(cmd));
 
-	local_irq_save(flags);
 	hostdata->issue_queue = NULL;
 	hostdata->connected = NULL;
 	hostdata->disconnected_queue = NULL;



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

* [PATCH 11/71] ncr5380: Simplify bus reset handlers
@ 2015-11-18  8:35   ` Finn Thain
  0 siblings, 0 replies; 268+ messages in thread
From: Finn Thain @ 2015-11-18  8:35 UTC (permalink / raw)
  To: James E.J. Bottomley, Michael Schmitz, linux-m68k, linux-scsi,
	linux-kernel

[-- Attachment #1: ncr5380-cleanup-bus-reset-handler --]
[-- Type: text/plain, Size: 4071 bytes --]

Make use of do_reset() in the bus reset handler in atari_NCR5380.c. The
version in NCR5380.c already does so. Keep them in sync.

Signed-off-by: Finn Thain <fthain@telegraphics.com.au>

---

Bus reset handlers in both core drivers still have serious problems for
EH purposes. Those problems are addressed later in this series.

---
 drivers/scsi/NCR5380.c       |   20 +++++++++++---------
 drivers/scsi/atari_NCR5380.c |   30 ++++++++++++------------------
 2 files changed, 23 insertions(+), 27 deletions(-)

Index: linux/drivers/scsi/NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/NCR5380.c	2015-11-18 19:33:15.000000000 +1100
+++ linux/drivers/scsi/NCR5380.c	2015-11-18 19:33:17.000000000 +1100
@@ -668,7 +668,7 @@ static void prepare_info(struct Scsi_Hos
  *	Locks: called functions disable irqs
  */
 
-static void NCR5380_print_status(struct Scsi_Host *instance)
+static void __maybe_unused NCR5380_print_status(struct Scsi_Host *instance)
 {
 	NCR5380_dprint(NDEBUG_ANY, instance);
 	NCR5380_dprint_phase(NDEBUG_ANY, instance);
@@ -2693,24 +2693,26 @@ static int NCR5380_abort(struct scsi_cmn
 }
 
 
-/* 
- * Function : int NCR5380_bus_reset (struct scsi_cmnd *cmd)
- * 
- * Purpose : reset the SCSI bus.
- *
- * Returns : SUCCESS
+/**
+ * NCR5380_bus_reset - reset the SCSI bus
+ * @cmd: SCSI command undergoing EH
  *
- * Locks: host lock taken by caller
+ * Returns SUCCESS
  */
 
 static int NCR5380_bus_reset(struct scsi_cmnd *cmd)
 {
 	struct Scsi_Host *instance = cmd->device->host;
 
+	spin_lock_irq(instance->host_lock);
+
+#if (NDEBUG & NDEBUG_ANY)
+	scmd_printk(KERN_INFO, cmd, "performing bus reset\n");
 	NCR5380_print_status(instance);
+#endif
 
-	spin_lock_irq(instance->host_lock);
 	do_reset(instance);
+
 	spin_unlock_irq(instance->host_lock);
 
 	return SUCCESS;
Index: linux/drivers/scsi/atari_NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/atari_NCR5380.c	2015-11-18 19:33:15.000000000 +1100
+++ linux/drivers/scsi/atari_NCR5380.c	2015-11-18 19:33:17.000000000 +1100
@@ -719,7 +719,7 @@ static void lprint_Scsi_Cmnd(struct scsi
 	printk("\n");
 }
 
-static void NCR5380_print_status(struct Scsi_Host *instance)
+static void __maybe_unused NCR5380_print_status(struct Scsi_Host *instance)
 {
 	struct NCR5380_hostdata *hostdata;
 	struct scsi_cmnd *ptr;
@@ -2982,13 +2982,11 @@ int NCR5380_abort(struct scsi_cmnd *cmd)
 }
 
 
-/*
- * Function : int NCR5380_reset (struct scsi_cmnd *cmd)
- *
- * Purpose : reset the SCSI bus.
- *
- * Returns : SUCCESS or FAILURE
+/**
+ * NCR5380_bus_reset - reset the SCSI bus
+ * @cmd: SCSI command undergoing EH
  *
+ * Returns SUCCESS
  */
 
 static int NCR5380_bus_reset(struct scsi_cmnd *cmd)
@@ -2998,22 +2996,19 @@ static int NCR5380_bus_reset(struct scsi
 	int i;
 	unsigned long flags;
 
+	local_irq_save(flags);
+
+#if (NDEBUG & NDEBUG_ANY)
+	scmd_printk(KERN_INFO, cmd, "performing bus reset\n");
 	NCR5380_print_status(instance);
+#endif
+
+	do_reset(instance);
 
-	/* get in phase */
-	NCR5380_write(TARGET_COMMAND_REG,
-		      PHASE_SR_TO_TCR(NCR5380_read(STATUS_REG)));
-	/* assert RST */
-	NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_RST);
-	udelay(40);
 	/* reset NCR registers */
-	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);
-	/* ++roman: reset interrupt condition! otherwise no interrupts don't get
-	 * through anymore ... */
-	(void)NCR5380_read(RESET_PARITY_INTERRUPT_REG);
 
 	/* After the reset, there are no more connected or disconnected commands
 	 * and no busy units; so clear the low-level status here to avoid
@@ -3028,7 +3023,6 @@ static int NCR5380_bus_reset(struct scsi
 	if (hostdata->disconnected_queue)
 		dprintk(NDEBUG_ABORT, "scsi%d: reset aborted disconnected command(s)\n", H_NO(cmd));
 
-	local_irq_save(flags);
 	hostdata->issue_queue = NULL;
 	hostdata->connected = NULL;
 	hostdata->disconnected_queue = NULL;

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

* [PATCH 12/71] ncr5380: Remove unused hostdata->aborted flag
  2015-11-18  8:34 ` Finn Thain
@ 2015-11-18  8:35   ` Finn Thain
  -1 siblings, 0 replies; 268+ messages in thread
From: Finn Thain @ 2015-11-18  8:35 UTC (permalink / raw)
  To: James E.J. Bottomley, Michael Schmitz, linux-m68k, linux-scsi,
	linux-kernel

[-- Attachment #1: ncr5380-remove-unused-aborted-flag --]
[-- Type: text/plain, Size: 2509 bytes --]

The aborted flag was introduced in v1.1.38 but never used. Remove it.

Signed-off-by: Finn Thain <fthain@telegraphics.com.au>

---
 drivers/scsi/NCR5380.c       |    2 --
 drivers/scsi/NCR5380.h       |    1 -
 drivers/scsi/atari_NCR5380.c |    2 --
 3 files changed, 5 deletions(-)

Index: linux/drivers/scsi/NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/NCR5380.c	2015-11-18 19:33:17.000000000 +1100
+++ linux/drivers/scsi/NCR5380.c	2015-11-18 19:33:18.000000000 +1100
@@ -781,7 +781,6 @@ static int NCR5380_init(struct Scsi_Host
 	if(in_interrupt())
 		printk(KERN_ERR "NCR5380_init called with interrupts off!\n");
 
-	hostdata->aborted = 0;
 	hostdata->id_mask = 1 << instance->this_id;
 	for (i = hostdata->id_mask; i <= 0x80; i <<= 1)
 		if (i > hostdata->id_mask)
@@ -2574,7 +2573,6 @@ static int NCR5380_abort(struct scsi_cmn
 
 	if (hostdata->connected == cmd) {
 		dprintk(NDEBUG_ABORT, "scsi%d : aborting connected command\n", instance->host_no);
-		hostdata->aborted = 1;
 /*
  * We should perform BSY checking, and make sure we haven't slipped
  * into BUS FREE.
Index: linux/drivers/scsi/atari_NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/atari_NCR5380.c	2015-11-18 19:33:17.000000000 +1100
+++ linux/drivers/scsi/atari_NCR5380.c	2015-11-18 19:33:18.000000000 +1100
@@ -813,7 +813,6 @@ static int __init NCR5380_init(struct Sc
 	SETUP_HOSTDATA(instance);
 
 	hostdata->host = instance;
-	hostdata->aborted = 0;
 	hostdata->id_mask = 1 << instance->this_id;
 	hostdata->id_higher_mask = 0;
 	for (i = hostdata->id_mask; i <= 0x80; i <<= 1)
@@ -2834,7 +2833,6 @@ int NCR5380_abort(struct scsi_cmnd *cmd)
 		 */
 
 		if (do_abort(instance) == 0) {
-			hostdata->aborted = 1;
 			hostdata->connected = NULL;
 			cmd->result = DID_ABORT << 16;
 #ifdef SUPPORT_TAGS
Index: linux/drivers/scsi/NCR5380.h
===================================================================
--- linux.orig/drivers/scsi/NCR5380.h	2015-11-18 19:33:15.000000000 +1100
+++ linux/drivers/scsi/NCR5380.h	2015-11-18 19:33:18.000000000 +1100
@@ -271,7 +271,6 @@ struct NCR5380_hostdata {
 	volatile int restart_select;		/* we have disconnected,
 						   used to restart 
 						   NCR5380_select() */
-	volatile unsigned aborted:1;		/* flag, says aborted */
 	int flags;
 	unsigned long time_expires;		/* in jiffies, set prior to sleeping */
 	int select_time;			/* timer in select for target response */



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

* [PATCH 12/71] ncr5380: Remove unused hostdata->aborted flag
@ 2015-11-18  8:35   ` Finn Thain
  0 siblings, 0 replies; 268+ messages in thread
From: Finn Thain @ 2015-11-18  8:35 UTC (permalink / raw)
  To: James E.J. Bottomley, Michael Schmitz, linux-m68k, linux-scsi,
	linux-kernel

[-- Attachment #1: ncr5380-remove-unused-aborted-flag --]
[-- Type: text/plain, Size: 2507 bytes --]

The aborted flag was introduced in v1.1.38 but never used. Remove it.

Signed-off-by: Finn Thain <fthain@telegraphics.com.au>

---
 drivers/scsi/NCR5380.c       |    2 --
 drivers/scsi/NCR5380.h       |    1 -
 drivers/scsi/atari_NCR5380.c |    2 --
 3 files changed, 5 deletions(-)

Index: linux/drivers/scsi/NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/NCR5380.c	2015-11-18 19:33:17.000000000 +1100
+++ linux/drivers/scsi/NCR5380.c	2015-11-18 19:33:18.000000000 +1100
@@ -781,7 +781,6 @@ static int NCR5380_init(struct Scsi_Host
 	if(in_interrupt())
 		printk(KERN_ERR "NCR5380_init called with interrupts off!\n");
 
-	hostdata->aborted = 0;
 	hostdata->id_mask = 1 << instance->this_id;
 	for (i = hostdata->id_mask; i <= 0x80; i <<= 1)
 		if (i > hostdata->id_mask)
@@ -2574,7 +2573,6 @@ static int NCR5380_abort(struct scsi_cmn
 
 	if (hostdata->connected == cmd) {
 		dprintk(NDEBUG_ABORT, "scsi%d : aborting connected command\n", instance->host_no);
-		hostdata->aborted = 1;
 /*
  * We should perform BSY checking, and make sure we haven't slipped
  * into BUS FREE.
Index: linux/drivers/scsi/atari_NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/atari_NCR5380.c	2015-11-18 19:33:17.000000000 +1100
+++ linux/drivers/scsi/atari_NCR5380.c	2015-11-18 19:33:18.000000000 +1100
@@ -813,7 +813,6 @@ static int __init NCR5380_init(struct Sc
 	SETUP_HOSTDATA(instance);
 
 	hostdata->host = instance;
-	hostdata->aborted = 0;
 	hostdata->id_mask = 1 << instance->this_id;
 	hostdata->id_higher_mask = 0;
 	for (i = hostdata->id_mask; i <= 0x80; i <<= 1)
@@ -2834,7 +2833,6 @@ int NCR5380_abort(struct scsi_cmnd *cmd)
 		 */
 
 		if (do_abort(instance) == 0) {
-			hostdata->aborted = 1;
 			hostdata->connected = NULL;
 			cmd->result = DID_ABORT << 16;
 #ifdef SUPPORT_TAGS
Index: linux/drivers/scsi/NCR5380.h
===================================================================
--- linux.orig/drivers/scsi/NCR5380.h	2015-11-18 19:33:15.000000000 +1100
+++ linux/drivers/scsi/NCR5380.h	2015-11-18 19:33:18.000000000 +1100
@@ -271,7 +271,6 @@ struct NCR5380_hostdata {
 	volatile int restart_select;		/* we have disconnected,
 						   used to restart 
 						   NCR5380_select() */
-	volatile unsigned aborted:1;		/* flag, says aborted */
 	int flags;
 	unsigned long time_expires;		/* in jiffies, set prior to sleeping */
 	int select_time;			/* timer in select for target response */

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

* [PATCH 13/71] ncr5380: Remove redundant register writes
  2015-11-18  8:34 ` Finn Thain
@ 2015-11-18  8:35   ` Finn Thain
  -1 siblings, 0 replies; 268+ messages in thread
From: Finn Thain @ 2015-11-18  8:35 UTC (permalink / raw)
  To: James E.J. Bottomley, Michael Schmitz, linux-m68k, linux-scsi,
	linux-kernel

[-- Attachment #1: ncr5380-remove-double-register-writes --]
[-- Type: text/plain, Size: 2167 bytes --]

Remove the duplicate write to the Select Enable Register that appeared
in v1.1.38.

Also remove the redundant write to Initiator Command Register prior to
calling do_abort().

Signed-off-by: Finn Thain <fthain@telegraphics.com.au>

---
 drivers/scsi/NCR5380.c       |    2 --
 drivers/scsi/atari_NCR5380.c |    3 ---
 2 files changed, 5 deletions(-)

Index: linux/drivers/scsi/NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/NCR5380.c	2015-11-18 19:33:18.000000000 +1100
+++ linux/drivers/scsi/NCR5380.c	2015-11-18 19:33:19.000000000 +1100
@@ -1384,7 +1384,6 @@ part2:
 		cmd->scsi_done(cmd);
 		NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
 		dprintk(NDEBUG_SELECTION, "scsi%d : target did not respond within 250ms\n", instance->host_no);
-		NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
 		return 0;
 	}
 	hostdata->targets_present |= (1 << scmd_id(cmd));
@@ -2076,7 +2075,6 @@ static void NCR5380_information_transfer
 						scmd_printk(KERN_INFO, cmd,
 							    "switching to slow handshake\n");
 						cmd->device->borken = 1;
-						NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_ATN);
 						sink = 1;
 						do_abort(instance);
 						cmd->result = DID_ERROR << 16;
Index: linux/drivers/scsi/atari_NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/atari_NCR5380.c	2015-11-18 19:33:18.000000000 +1100
+++ linux/drivers/scsi/atari_NCR5380.c	2015-11-18 19:33:19.000000000 +1100
@@ -1640,7 +1640,6 @@ static int NCR5380_select(struct Scsi_Ho
 		cmd->scsi_done(cmd);
 		NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
 		dprintk(NDEBUG_SELECTION, "scsi%d: target did not respond within 250ms\n", HOSTNO);
-		NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
 		return 0;
 	}
 
@@ -2192,8 +2191,6 @@ static void NCR5380_information_transfer
 						scmd_printk(KERN_INFO, cmd,
 							"switching to slow handshake\n");
 						cmd->device->borken = 1;
-						NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE |
-							ICR_ASSERT_ATN);
 						sink = 1;
 						do_abort(instance);
 						cmd->result = DID_ERROR << 16;



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

* [PATCH 13/71] ncr5380: Remove redundant register writes
@ 2015-11-18  8:35   ` Finn Thain
  0 siblings, 0 replies; 268+ messages in thread
From: Finn Thain @ 2015-11-18  8:35 UTC (permalink / raw)
  To: James E.J. Bottomley, Michael Schmitz, linux-m68k, linux-scsi,
	linux-kernel

[-- Attachment #1: ncr5380-remove-double-register-writes --]
[-- Type: text/plain, Size: 2165 bytes --]

Remove the duplicate write to the Select Enable Register that appeared
in v1.1.38.

Also remove the redundant write to Initiator Command Register prior to
calling do_abort().

Signed-off-by: Finn Thain <fthain@telegraphics.com.au>

---
 drivers/scsi/NCR5380.c       |    2 --
 drivers/scsi/atari_NCR5380.c |    3 ---
 2 files changed, 5 deletions(-)

Index: linux/drivers/scsi/NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/NCR5380.c	2015-11-18 19:33:18.000000000 +1100
+++ linux/drivers/scsi/NCR5380.c	2015-11-18 19:33:19.000000000 +1100
@@ -1384,7 +1384,6 @@ part2:
 		cmd->scsi_done(cmd);
 		NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
 		dprintk(NDEBUG_SELECTION, "scsi%d : target did not respond within 250ms\n", instance->host_no);
-		NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
 		return 0;
 	}
 	hostdata->targets_present |= (1 << scmd_id(cmd));
@@ -2076,7 +2075,6 @@ static void NCR5380_information_transfer
 						scmd_printk(KERN_INFO, cmd,
 							    "switching to slow handshake\n");
 						cmd->device->borken = 1;
-						NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_ATN);
 						sink = 1;
 						do_abort(instance);
 						cmd->result = DID_ERROR << 16;
Index: linux/drivers/scsi/atari_NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/atari_NCR5380.c	2015-11-18 19:33:18.000000000 +1100
+++ linux/drivers/scsi/atari_NCR5380.c	2015-11-18 19:33:19.000000000 +1100
@@ -1640,7 +1640,6 @@ static int NCR5380_select(struct Scsi_Ho
 		cmd->scsi_done(cmd);
 		NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
 		dprintk(NDEBUG_SELECTION, "scsi%d: target did not respond within 250ms\n", HOSTNO);
-		NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
 		return 0;
 	}
 
@@ -2192,8 +2191,6 @@ static void NCR5380_information_transfer
 						scmd_printk(KERN_INFO, cmd,
 							"switching to slow handshake\n");
 						cmd->device->borken = 1;
-						NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE |
-							ICR_ASSERT_ATN);
 						sink = 1;
 						do_abort(instance);
 						cmd->result = DID_ERROR << 16;

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

* [PATCH 14/71] ncr5380: Use return instead of goto in NCR5380_select()
  2015-11-18  8:34 ` Finn Thain
@ 2015-11-18  8:35   ` Finn Thain
  -1 siblings, 0 replies; 268+ messages in thread
From: Finn Thain @ 2015-11-18  8:35 UTC (permalink / raw)
  To: James E.J. Bottomley, Michael Schmitz, linux-m68k, linux-scsi,
	linux-kernel

[-- Attachment #1: ncr5380-use-return-instead-of-goto --]
[-- Type: text/plain, Size: 4693 bytes --]

The "failed" label in NCR5380_select() is not helpful. Some failures
return 0, others -1. Use return instead of goto to improve clarity and
brevity, like atari_NCR5380.c does. Fix the relevant comments.

Signed-off-by: Finn Thain <fthain@telegraphics.com.au>

---
 drivers/scsi/NCR5380.c       |   30 ++++++++----------------------
 drivers/scsi/atari_NCR5380.c |    6 +++---
 2 files changed, 11 insertions(+), 25 deletions(-)

Index: linux/drivers/scsi/NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/NCR5380.c	2015-11-18 19:33:19.000000000 +1100
+++ linux/drivers/scsi/NCR5380.c	2015-11-18 19:33:20.000000000 +1100
@@ -997,16 +997,6 @@ static void NCR5380_main(struct work_str
 					 */
 					dprintk(NDEBUG_MAIN|NDEBUG_QUEUES, "scsi%d : main() : command for target %d lun %llu removed from issue_queue\n", instance->host_no, tmp->device->id, tmp->device->lun);
 	
-					/*
-					 * A successful selection is defined as one that 
-					 * leaves us with the command connected and 
-					 * in hostdata->connected, OR has terminated the
-					 * command.
-					 *
-					 * With successful commands, we fall through
-					 * and see if we can do an information transfer,
-					 * with failures we will restart.
-					 */
 					hostdata->selecting = NULL;
 					/* RvC: have to preset this to indicate a new command is being performed */
 
@@ -1162,9 +1152,10 @@ static irqreturn_t NCR5380_intr(int dumm
  * Inputs : instance - instantiation of the 5380 driver on which this 
  *      target lives, cmd - SCSI command to execute.
  * 
- * Returns : -1 if selection could not execute for some reason,
- *      0 if selection succeeded or failed because the target 
- *      did not respond.
+ * Returns : -1 if selection failed but should be retried.
+ *      0 if selection failed and should not be retried.
+ *      0 if selection succeeded completely (hostdata->connected == cmd).
+ *      0 if selection in progress (hostdata->selecting == cmd).
  *
  * Side effects : 
  *      If bus busy, arbitration failed, etc, NCR5380_select() will exit 
@@ -1224,7 +1215,7 @@ static int NCR5380_select(struct Scsi_Ho
 		printk(KERN_DEBUG "scsi: arbitration timeout at %d\n", __LINE__);
 		NCR5380_write(MODE_REG, MR_BASE);
 		NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
-		goto failed;
+		return -1;
 	}
 
 	dprintk(NDEBUG_ARBITRATION, "scsi%d : arbitration complete\n", instance->host_no);
@@ -1242,7 +1233,7 @@ static int NCR5380_select(struct Scsi_Ho
 	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);
 		dprintk(NDEBUG_ARBITRATION, "scsi%d : lost arbitration, deasserting MR_ARBITRATE\n", instance->host_no);
-		goto failed;
+		return -1;
 	}
 	NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_SEL);
 
@@ -1255,7 +1246,7 @@ static int NCR5380_select(struct Scsi_Ho
 		NCR5380_write(MODE_REG, MR_BASE);
 		NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
 		dprintk(NDEBUG_ARBITRATION, "scsi%d : lost arbitration, deasserting ICR_ASSERT_SEL\n", instance->host_no);
-		goto failed;
+		return -1;
 	}
 	/* 
 	 * Again, bus clear + bus settle time is 1.2us, however, this is 
@@ -1412,7 +1403,7 @@ part2:
 	if(err) {
 		printk(KERN_ERR "scsi%d: timeout at NCR5380.c:%d\n", instance->host_no, __LINE__);
 		NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
-		goto failed;
+		return -1;
 	}
 
 	dprintk(NDEBUG_SELECTION, "scsi%d : target %d selected, going into MESSAGE OUT phase.\n", instance->host_no, cmd->device->id);
@@ -1433,11 +1424,6 @@ part2:
 	initialize_SCp(cmd);
 
 	return 0;
-
-	/* Selection failed */
-failed:
-	return -1;
-
 }
 
 /* 
Index: linux/drivers/scsi/atari_NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/atari_NCR5380.c	2015-11-18 19:33:19.000000000 +1100
+++ linux/drivers/scsi/atari_NCR5380.c	2015-11-18 19:33:20.000000000 +1100
@@ -1382,9 +1382,9 @@ static irqreturn_t NCR5380_intr(int irq,
  * Inputs : instance - instantiation of the 5380 driver on which this
  *	target lives, cmd - SCSI command to execute.
  *
- * Returns : -1 if selection could not execute for some reason,
- *	0 if selection succeeded or failed because the target
- *	did not respond.
+ * Returns : -1 if selection failed but should be retried.
+ *      0 if selection failed and should not be retried.
+ *      0 if selection succeeded completely (hostdata->connected == cmd).
  *
  * Side effects :
  *	If bus busy, arbitration failed, etc, NCR5380_select() will exit



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

* [PATCH 14/71] ncr5380: Use return instead of goto in NCR5380_select()
@ 2015-11-18  8:35   ` Finn Thain
  0 siblings, 0 replies; 268+ messages in thread
From: Finn Thain @ 2015-11-18  8:35 UTC (permalink / raw)
  To: James E.J. Bottomley, Michael Schmitz, linux-m68k, linux-scsi,
	linux-kernel

[-- Attachment #1: ncr5380-use-return-instead-of-goto --]
[-- Type: text/plain, Size: 4691 bytes --]

The "failed" label in NCR5380_select() is not helpful. Some failures
return 0, others -1. Use return instead of goto to improve clarity and
brevity, like atari_NCR5380.c does. Fix the relevant comments.

Signed-off-by: Finn Thain <fthain@telegraphics.com.au>

---
 drivers/scsi/NCR5380.c       |   30 ++++++++----------------------
 drivers/scsi/atari_NCR5380.c |    6 +++---
 2 files changed, 11 insertions(+), 25 deletions(-)

Index: linux/drivers/scsi/NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/NCR5380.c	2015-11-18 19:33:19.000000000 +1100
+++ linux/drivers/scsi/NCR5380.c	2015-11-18 19:33:20.000000000 +1100
@@ -997,16 +997,6 @@ static void NCR5380_main(struct work_str
 					 */
 					dprintk(NDEBUG_MAIN|NDEBUG_QUEUES, "scsi%d : main() : command for target %d lun %llu removed from issue_queue\n", instance->host_no, tmp->device->id, tmp->device->lun);
 	
-					/*
-					 * A successful selection is defined as one that 
-					 * leaves us with the command connected and 
-					 * in hostdata->connected, OR has terminated the
-					 * command.
-					 *
-					 * With successful commands, we fall through
-					 * and see if we can do an information transfer,
-					 * with failures we will restart.
-					 */
 					hostdata->selecting = NULL;
 					/* RvC: have to preset this to indicate a new command is being performed */
 
@@ -1162,9 +1152,10 @@ static irqreturn_t NCR5380_intr(int dumm
  * Inputs : instance - instantiation of the 5380 driver on which this 
  *      target lives, cmd - SCSI command to execute.
  * 
- * Returns : -1 if selection could not execute for some reason,
- *      0 if selection succeeded or failed because the target 
- *      did not respond.
+ * Returns : -1 if selection failed but should be retried.
+ *      0 if selection failed and should not be retried.
+ *      0 if selection succeeded completely (hostdata->connected == cmd).
+ *      0 if selection in progress (hostdata->selecting == cmd).
  *
  * Side effects : 
  *      If bus busy, arbitration failed, etc, NCR5380_select() will exit 
@@ -1224,7 +1215,7 @@ static int NCR5380_select(struct Scsi_Ho
 		printk(KERN_DEBUG "scsi: arbitration timeout at %d\n", __LINE__);
 		NCR5380_write(MODE_REG, MR_BASE);
 		NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
-		goto failed;
+		return -1;
 	}
 
 	dprintk(NDEBUG_ARBITRATION, "scsi%d : arbitration complete\n", instance->host_no);
@@ -1242,7 +1233,7 @@ static int NCR5380_select(struct Scsi_Ho
 	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);
 		dprintk(NDEBUG_ARBITRATION, "scsi%d : lost arbitration, deasserting MR_ARBITRATE\n", instance->host_no);
-		goto failed;
+		return -1;
 	}
 	NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_SEL);
 
@@ -1255,7 +1246,7 @@ static int NCR5380_select(struct Scsi_Ho
 		NCR5380_write(MODE_REG, MR_BASE);
 		NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
 		dprintk(NDEBUG_ARBITRATION, "scsi%d : lost arbitration, deasserting ICR_ASSERT_SEL\n", instance->host_no);
-		goto failed;
+		return -1;
 	}
 	/* 
 	 * Again, bus clear + bus settle time is 1.2us, however, this is 
@@ -1412,7 +1403,7 @@ part2:
 	if(err) {
 		printk(KERN_ERR "scsi%d: timeout at NCR5380.c:%d\n", instance->host_no, __LINE__);
 		NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
-		goto failed;
+		return -1;
 	}
 
 	dprintk(NDEBUG_SELECTION, "scsi%d : target %d selected, going into MESSAGE OUT phase.\n", instance->host_no, cmd->device->id);
@@ -1433,11 +1424,6 @@ part2:
 	initialize_SCp(cmd);
 
 	return 0;
-
-	/* Selection failed */
-failed:
-	return -1;
-
 }
 
 /* 
Index: linux/drivers/scsi/atari_NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/atari_NCR5380.c	2015-11-18 19:33:19.000000000 +1100
+++ linux/drivers/scsi/atari_NCR5380.c	2015-11-18 19:33:20.000000000 +1100
@@ -1382,9 +1382,9 @@ static irqreturn_t NCR5380_intr(int irq,
  * Inputs : instance - instantiation of the 5380 driver on which this
  *	target lives, cmd - SCSI command to execute.
  *
- * Returns : -1 if selection could not execute for some reason,
- *	0 if selection succeeded or failed because the target
- *	did not respond.
+ * Returns : -1 if selection failed but should be retried.
+ *      0 if selection failed and should not be retried.
+ *      0 if selection succeeded completely (hostdata->connected == cmd).
  *
  * Side effects :
  *	If bus busy, arbitration failed, etc, NCR5380_select() will exit

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

* [PATCH 15/71] ncr5380: Always escalate bad target time-out in NCR5380_select()
  2015-11-18  8:34 ` Finn Thain
@ 2015-11-18  8:35   ` Finn Thain
  -1 siblings, 0 replies; 268+ messages in thread
From: Finn Thain @ 2015-11-18  8:35 UTC (permalink / raw)
  To: James E.J. Bottomley, Michael Schmitz, linux-m68k, linux-scsi,
	linux-kernel

[-- Attachment #1: ncr5380-escalate-selection-timeout --]
[-- Type: text/plain, Size: 5748 bytes --]

Remove the restart_select and targets_present variables introduced in
Linux v1.1.38. The former was used only for a questionable debug printk
and the latter "so we can call a select failure a retryable condition".
Well, retrying select failure in general is a different problem to a
target that doesn't assert BSY. We need to handle these two cases
differently; the latter case can be left to the SCSI ML.

Signed-off-by: Finn Thain <fthain@telegraphics.com.au>

---
 drivers/scsi/NCR5380.c       |   13 -------------
 drivers/scsi/NCR5380.h       |    6 ------
 drivers/scsi/atari_NCR5380.c |   13 -------------
 3 files changed, 32 deletions(-)

Index: linux/drivers/scsi/NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/NCR5380.c	2015-11-18 19:33:20.000000000 +1100
+++ linux/drivers/scsi/NCR5380.c	2015-11-18 19:33:21.000000000 +1100
@@ -790,7 +790,6 @@ static int NCR5380_init(struct Scsi_Host
 #ifdef REAL_DMA
 	hostdata->dmalen = 0;
 #endif
-	hostdata->targets_present = 0;
 	hostdata->connected = NULL;
 	hostdata->issue_queue = NULL;
 	hostdata->disconnected_queue = NULL;
@@ -1186,8 +1185,6 @@ static int NCR5380_select(struct Scsi_Ho
 	if (hostdata->selecting)
 		goto part2;
 
-	hostdata->restart_select = 0;
-
 	NCR5380_dprint(NDEBUG_ARBITRATION, instance);
 	dprintk(NDEBUG_ARBITRATION, "scsi%d : starting arbitration, id = %d\n", instance->host_no, instance->this_id);
 
@@ -1363,21 +1360,12 @@ part2:
 
 	if (!(NCR5380_read(STATUS_REG) & SR_BSY)) {
 		NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
-		if (hostdata->targets_present & (1 << scmd_id(cmd))) {
-			printk(KERN_DEBUG "scsi%d : weirdness\n", instance->host_no);
-			if (hostdata->restart_select)
-				printk(KERN_DEBUG "\trestart select\n");
-			NCR5380_dprint(NDEBUG_SELECTION, instance);
-			NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
-			return -1;
-		}
 		cmd->result = DID_BAD_TARGET << 16;
 		cmd->scsi_done(cmd);
 		NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
 		dprintk(NDEBUG_SELECTION, "scsi%d : target did not respond within 250ms\n", instance->host_no);
 		return 0;
 	}
-	hostdata->targets_present |= (1 << scmd_id(cmd));
 
 	/*
 	 * Since we followed the SCSI spec, and raised ATN while SEL 
@@ -2382,7 +2370,6 @@ static void NCR5380_reselect(struct Scsi
 	 */
 
 	NCR5380_write(MODE_REG, MR_BASE);
-	hostdata->restart_select = 1;
 
 	target_mask = NCR5380_read(CURRENT_SCSI_DATA_REG) & ~(hostdata->id_mask);
 	dprintk(NDEBUG_SELECTION, "scsi%d : reselect\n", instance->host_no);
Index: linux/drivers/scsi/atari_NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/atari_NCR5380.c	2015-11-18 19:33:20.000000000 +1100
+++ linux/drivers/scsi/atari_NCR5380.c	2015-11-18 19:33:21.000000000 +1100
@@ -826,7 +826,6 @@ static int __init NCR5380_init(struct Sc
 #if defined (REAL_DMA)
 	hostdata->dma_len = 0;
 #endif
-	hostdata->targets_present = 0;
 	hostdata->connected = NULL;
 	hostdata->issue_queue = NULL;
 	hostdata->disconnected_queue = NULL;
@@ -1409,7 +1408,6 @@ static int NCR5380_select(struct Scsi_Ho
 	unsigned long timeout;
 	unsigned long flags;
 
-	hostdata->restart_select = 0;
 	NCR5380_dprint(NDEBUG_ARBITRATION, instance);
 	dprintk(NDEBUG_ARBITRATION, "scsi%d: starting arbitration, id = %d\n", HOSTNO,
 		   instance->this_id);
@@ -1625,14 +1623,6 @@ static int NCR5380_select(struct Scsi_Ho
 
 	if (!(NCR5380_read(STATUS_REG) & SR_BSY)) {
 		NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
-		if (hostdata->targets_present & (1 << cmd->device->id)) {
-			printk(KERN_ERR "scsi%d: weirdness\n", HOSTNO);
-			if (hostdata->restart_select)
-				printk(KERN_NOTICE "\trestart select\n");
-			NCR5380_dprint(NDEBUG_ANY, instance);
-			NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
-			return -1;
-		}
 		cmd->result = DID_BAD_TARGET << 16;
 #ifdef SUPPORT_TAGS
 		cmd_free_tag(cmd);
@@ -1643,8 +1633,6 @@ static int NCR5380_select(struct Scsi_Ho
 		return 0;
 	}
 
-	hostdata->targets_present |= (1 << cmd->device->id);
-
 	/*
 	 * Since we followed the SCSI spec, and raised ATN while SEL
 	 * was true but before BSY was false during selection, the information
@@ -2605,7 +2593,6 @@ static void NCR5380_reselect(struct Scsi
 	 */
 
 	NCR5380_write(MODE_REG, MR_BASE);
-	hostdata->restart_select = 1;
 
 	target_mask = NCR5380_read(CURRENT_SCSI_DATA_REG) & ~(hostdata->id_mask);
 
Index: linux/drivers/scsi/NCR5380.h
===================================================================
--- linux.orig/drivers/scsi/NCR5380.h	2015-11-18 19:33:18.000000000 +1100
+++ linux/drivers/scsi/NCR5380.h	2015-11-18 19:33:21.000000000 +1100
@@ -257,9 +257,6 @@ struct NCR5380_hostdata {
 	NCR5380_implementation_fields;		/* implementation specific */
 	struct Scsi_Host *host;			/* Host backpointer */
 	unsigned char id_mask, id_higher_mask;	/* 1 << id, all bits greater */
-	unsigned char targets_present;		/* targets we have connected
-						   to, so we can call a select
-						   failure a retryable condition */
 	volatile unsigned char busy[8];		/* index = target, bit = lun */
 #if defined(REAL_DMA) || defined(REAL_DMA_POLL)
 	volatile int dma_len;			/* requested length of DMA */
@@ -268,9 +265,6 @@ struct NCR5380_hostdata {
 	volatile struct scsi_cmnd *connected;	/* currently connected command */
 	volatile struct scsi_cmnd *issue_queue;	/* waiting to be issued */
 	volatile struct scsi_cmnd *disconnected_queue;	/* waiting for reconnect */
-	volatile int restart_select;		/* we have disconnected,
-						   used to restart 
-						   NCR5380_select() */
 	int flags;
 	unsigned long time_expires;		/* in jiffies, set prior to sleeping */
 	int select_time;			/* timer in select for target response */



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

* [PATCH 15/71] ncr5380: Always escalate bad target time-out in NCR5380_select()
@ 2015-11-18  8:35   ` Finn Thain
  0 siblings, 0 replies; 268+ messages in thread
From: Finn Thain @ 2015-11-18  8:35 UTC (permalink / raw)
  To: James E.J. Bottomley, Michael Schmitz, linux-m68k, linux-scsi,
	linux-kernel

[-- Attachment #1: ncr5380-escalate-selection-timeout --]
[-- Type: text/plain, Size: 5746 bytes --]

Remove the restart_select and targets_present variables introduced in
Linux v1.1.38. The former was used only for a questionable debug printk
and the latter "so we can call a select failure a retryable condition".
Well, retrying select failure in general is a different problem to a
target that doesn't assert BSY. We need to handle these two cases
differently; the latter case can be left to the SCSI ML.

Signed-off-by: Finn Thain <fthain@telegraphics.com.au>

---
 drivers/scsi/NCR5380.c       |   13 -------------
 drivers/scsi/NCR5380.h       |    6 ------
 drivers/scsi/atari_NCR5380.c |   13 -------------
 3 files changed, 32 deletions(-)

Index: linux/drivers/scsi/NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/NCR5380.c	2015-11-18 19:33:20.000000000 +1100
+++ linux/drivers/scsi/NCR5380.c	2015-11-18 19:33:21.000000000 +1100
@@ -790,7 +790,6 @@ static int NCR5380_init(struct Scsi_Host
 #ifdef REAL_DMA
 	hostdata->dmalen = 0;
 #endif
-	hostdata->targets_present = 0;
 	hostdata->connected = NULL;
 	hostdata->issue_queue = NULL;
 	hostdata->disconnected_queue = NULL;
@@ -1186,8 +1185,6 @@ static int NCR5380_select(struct Scsi_Ho
 	if (hostdata->selecting)
 		goto part2;
 
-	hostdata->restart_select = 0;
-
 	NCR5380_dprint(NDEBUG_ARBITRATION, instance);
 	dprintk(NDEBUG_ARBITRATION, "scsi%d : starting arbitration, id = %d\n", instance->host_no, instance->this_id);
 
@@ -1363,21 +1360,12 @@ part2:
 
 	if (!(NCR5380_read(STATUS_REG) & SR_BSY)) {
 		NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
-		if (hostdata->targets_present & (1 << scmd_id(cmd))) {
-			printk(KERN_DEBUG "scsi%d : weirdness\n", instance->host_no);
-			if (hostdata->restart_select)
-				printk(KERN_DEBUG "\trestart select\n");
-			NCR5380_dprint(NDEBUG_SELECTION, instance);
-			NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
-			return -1;
-		}
 		cmd->result = DID_BAD_TARGET << 16;
 		cmd->scsi_done(cmd);
 		NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
 		dprintk(NDEBUG_SELECTION, "scsi%d : target did not respond within 250ms\n", instance->host_no);
 		return 0;
 	}
-	hostdata->targets_present |= (1 << scmd_id(cmd));
 
 	/*
 	 * Since we followed the SCSI spec, and raised ATN while SEL 
@@ -2382,7 +2370,6 @@ static void NCR5380_reselect(struct Scsi
 	 */
 
 	NCR5380_write(MODE_REG, MR_BASE);
-	hostdata->restart_select = 1;
 
 	target_mask = NCR5380_read(CURRENT_SCSI_DATA_REG) & ~(hostdata->id_mask);
 	dprintk(NDEBUG_SELECTION, "scsi%d : reselect\n", instance->host_no);
Index: linux/drivers/scsi/atari_NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/atari_NCR5380.c	2015-11-18 19:33:20.000000000 +1100
+++ linux/drivers/scsi/atari_NCR5380.c	2015-11-18 19:33:21.000000000 +1100
@@ -826,7 +826,6 @@ static int __init NCR5380_init(struct Sc
 #if defined (REAL_DMA)
 	hostdata->dma_len = 0;
 #endif
-	hostdata->targets_present = 0;
 	hostdata->connected = NULL;
 	hostdata->issue_queue = NULL;
 	hostdata->disconnected_queue = NULL;
@@ -1409,7 +1408,6 @@ static int NCR5380_select(struct Scsi_Ho
 	unsigned long timeout;
 	unsigned long flags;
 
-	hostdata->restart_select = 0;
 	NCR5380_dprint(NDEBUG_ARBITRATION, instance);
 	dprintk(NDEBUG_ARBITRATION, "scsi%d: starting arbitration, id = %d\n", HOSTNO,
 		   instance->this_id);
@@ -1625,14 +1623,6 @@ static int NCR5380_select(struct Scsi_Ho
 
 	if (!(NCR5380_read(STATUS_REG) & SR_BSY)) {
 		NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
-		if (hostdata->targets_present & (1 << cmd->device->id)) {
-			printk(KERN_ERR "scsi%d: weirdness\n", HOSTNO);
-			if (hostdata->restart_select)
-				printk(KERN_NOTICE "\trestart select\n");
-			NCR5380_dprint(NDEBUG_ANY, instance);
-			NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
-			return -1;
-		}
 		cmd->result = DID_BAD_TARGET << 16;
 #ifdef SUPPORT_TAGS
 		cmd_free_tag(cmd);
@@ -1643,8 +1633,6 @@ static int NCR5380_select(struct Scsi_Ho
 		return 0;
 	}
 
-	hostdata->targets_present |= (1 << cmd->device->id);
-
 	/*
 	 * Since we followed the SCSI spec, and raised ATN while SEL
 	 * was true but before BSY was false during selection, the information
@@ -2605,7 +2593,6 @@ static void NCR5380_reselect(struct Scsi
 	 */
 
 	NCR5380_write(MODE_REG, MR_BASE);
-	hostdata->restart_select = 1;
 
 	target_mask = NCR5380_read(CURRENT_SCSI_DATA_REG) & ~(hostdata->id_mask);
 
Index: linux/drivers/scsi/NCR5380.h
===================================================================
--- linux.orig/drivers/scsi/NCR5380.h	2015-11-18 19:33:18.000000000 +1100
+++ linux/drivers/scsi/NCR5380.h	2015-11-18 19:33:21.000000000 +1100
@@ -257,9 +257,6 @@ struct NCR5380_hostdata {
 	NCR5380_implementation_fields;		/* implementation specific */
 	struct Scsi_Host *host;			/* Host backpointer */
 	unsigned char id_mask, id_higher_mask;	/* 1 << id, all bits greater */
-	unsigned char targets_present;		/* targets we have connected
-						   to, so we can call a select
-						   failure a retryable condition */
 	volatile unsigned char busy[8];		/* index = target, bit = lun */
 #if defined(REAL_DMA) || defined(REAL_DMA_POLL)
 	volatile int dma_len;			/* requested length of DMA */
@@ -268,9 +265,6 @@ struct NCR5380_hostdata {
 	volatile struct scsi_cmnd *connected;	/* currently connected command */
 	volatile struct scsi_cmnd *issue_queue;	/* waiting to be issued */
 	volatile struct scsi_cmnd *disconnected_queue;	/* waiting for reconnect */
-	volatile int restart_select;		/* we have disconnected,
-						   used to restart 
-						   NCR5380_select() */
 	int flags;
 	unsigned long time_expires;		/* in jiffies, set prior to sleeping */
 	int select_time;			/* timer in select for target response */

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

* [PATCH 16/71] ncr5380: Proceed with next command after NCR5380_select() calls scsi_done
  2015-11-18  8:34 ` Finn Thain
@ 2015-11-18  8:35   ` Finn Thain
  -1 siblings, 0 replies; 268+ messages in thread
From: Finn Thain @ 2015-11-18  8:35 UTC (permalink / raw)
  To: James E.J. Bottomley, Michael Schmitz, linux-m68k, linux-scsi,
	linux-kernel

[-- Attachment #1: ncr5380-drop-completed-command --]
[-- Type: text/plain, Size: 3393 bytes --]

If a target disappears from the SCSI bus, NCR5380_select() may
subsequently fail with a time-out. In this situation, scsi_done is
called and NCR5380_select() returns 0. Both hostdata->connected and
hostdata->selecting are NULL and the main loop should proceed with
the next command in the issue queue. Clarify this logic.

Signed-off-by: Finn Thain <fthain@telegraphics.com.au>

---

Good code style would be,

	if (this) {
		/* do stuff */
	}

rather than,

	if (!this) {
	} else {
		/* do stuff */
	}

But I've used the latter form at this point in the series for a cleaner
diff between NCR5380.c and atari_NC5380.c, making it easier to gradually
reduce discrepancies. Code style gets fixed up along the way.

---
 drivers/scsi/NCR5380.c       |    8 ++++++--
 drivers/scsi/atari_NCR5380.c |    8 ++++----
 2 files changed, 10 insertions(+), 6 deletions(-)

Index: linux/drivers/scsi/NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/NCR5380.c	2015-11-18 19:33:21.000000000 +1100
+++ linux/drivers/scsi/NCR5380.c	2015-11-18 19:33:23.000000000 +1100
@@ -1007,14 +1007,18 @@ static void NCR5380_main(struct work_str
 					 */
 
 					if (!NCR5380_select(instance, tmp)) {
-						break;
+						/* OK or bad target */
 					} else {
+						/* Need to retry */
 						LIST(tmp, hostdata->issue_queue);
 						tmp->host_scribble = (unsigned char *) hostdata->issue_queue;
 						hostdata->issue_queue = tmp;
 						done = 0;
 						dprintk(NDEBUG_MAIN|NDEBUG_QUEUES, "scsi%d : main(): select() failed, returned to issue_queue\n", instance->host_no);
 					}
+					if (hostdata->connected ||
+					    hostdata->selecting)
+						break;
 					/* lock held here still */
 				}	/* if target/lun is not busy */
 			}	/* for */
@@ -1024,7 +1028,7 @@ static void NCR5380_main(struct work_str
 			tmp = (struct scsi_cmnd *) hostdata->selecting;
 			/* Selection will drop and retake the lock */
 			if (!NCR5380_select(instance, tmp)) {
-				/* Ok ?? */
+				/* OK or bad target */
 			} else {
 				/* RvC: device failed, so we wait a long time
 				   this is needed for Mustek scanners, that
Index: linux/drivers/scsi/atari_NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/atari_NCR5380.c	2015-11-18 19:33:21.000000000 +1100
+++ linux/drivers/scsi/atari_NCR5380.c	2015-11-18 19:33:23.000000000 +1100
@@ -1139,13 +1139,13 @@ static void NCR5380_main(struct work_str
 					cmd_get_tag(tmp, tmp->cmnd[0] != REQUEST_SENSE);
 #endif
 					if (!NCR5380_select(instance, tmp)) {
+						/* OK or bad target */
 						local_irq_disable();
 						hostdata->retain_dma_intr--;
-						/* release if target did not response! */
 						maybe_release_dma_irq(instance);
 						local_irq_restore(flags);
-						break;
 					} else {
+						/* Need to retry */
 						local_irq_disable();
 						LIST(tmp, hostdata->issue_queue);
 						SET_NEXT(tmp, hostdata->issue_queue);
@@ -1157,9 +1157,9 @@ static void NCR5380_main(struct work_str
 						local_irq_restore(flags);
 						dprintk(NDEBUG_MAIN, "scsi%d: main(): select() failed, "
 							    "returned to issue_queue\n", HOSTNO);
-						if (hostdata->connected)
-							break;
 					}
+					if (hostdata->connected)
+						break;
 				} /* if target/lun/target queue is not busy */
 			} /* for issue_queue */
 		} /* if (!hostdata->connected) */



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

* [PATCH 16/71] ncr5380: Proceed with next command after NCR5380_select() calls scsi_done
@ 2015-11-18  8:35   ` Finn Thain
  0 siblings, 0 replies; 268+ messages in thread
From: Finn Thain @ 2015-11-18  8:35 UTC (permalink / raw)
  To: James E.J. Bottomley, Michael Schmitz, linux-m68k, linux-scsi,
	linux-kernel

[-- Attachment #1: ncr5380-drop-completed-command --]
[-- Type: text/plain, Size: 3391 bytes --]

If a target disappears from the SCSI bus, NCR5380_select() may
subsequently fail with a time-out. In this situation, scsi_done is
called and NCR5380_select() returns 0. Both hostdata->connected and
hostdata->selecting are NULL and the main loop should proceed with
the next command in the issue queue. Clarify this logic.

Signed-off-by: Finn Thain <fthain@telegraphics.com.au>

---

Good code style would be,

	if (this) {
		/* do stuff */
	}

rather than,

	if (!this) {
	} else {
		/* do stuff */
	}

But I've used the latter form at this point in the series for a cleaner
diff between NCR5380.c and atari_NC5380.c, making it easier to gradually
reduce discrepancies. Code style gets fixed up along the way.

---
 drivers/scsi/NCR5380.c       |    8 ++++++--
 drivers/scsi/atari_NCR5380.c |    8 ++++----
 2 files changed, 10 insertions(+), 6 deletions(-)

Index: linux/drivers/scsi/NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/NCR5380.c	2015-11-18 19:33:21.000000000 +1100
+++ linux/drivers/scsi/NCR5380.c	2015-11-18 19:33:23.000000000 +1100
@@ -1007,14 +1007,18 @@ static void NCR5380_main(struct work_str
 					 */
 
 					if (!NCR5380_select(instance, tmp)) {
-						break;
+						/* OK or bad target */
 					} else {
+						/* Need to retry */
 						LIST(tmp, hostdata->issue_queue);
 						tmp->host_scribble = (unsigned char *) hostdata->issue_queue;
 						hostdata->issue_queue = tmp;
 						done = 0;
 						dprintk(NDEBUG_MAIN|NDEBUG_QUEUES, "scsi%d : main(): select() failed, returned to issue_queue\n", instance->host_no);
 					}
+					if (hostdata->connected ||
+					    hostdata->selecting)
+						break;
 					/* lock held here still */
 				}	/* if target/lun is not busy */
 			}	/* for */
@@ -1024,7 +1028,7 @@ static void NCR5380_main(struct work_str
 			tmp = (struct scsi_cmnd *) hostdata->selecting;
 			/* Selection will drop and retake the lock */
 			if (!NCR5380_select(instance, tmp)) {
-				/* Ok ?? */
+				/* OK or bad target */
 			} else {
 				/* RvC: device failed, so we wait a long time
 				   this is needed for Mustek scanners, that
Index: linux/drivers/scsi/atari_NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/atari_NCR5380.c	2015-11-18 19:33:21.000000000 +1100
+++ linux/drivers/scsi/atari_NCR5380.c	2015-11-18 19:33:23.000000000 +1100
@@ -1139,13 +1139,13 @@ static void NCR5380_main(struct work_str
 					cmd_get_tag(tmp, tmp->cmnd[0] != REQUEST_SENSE);
 #endif
 					if (!NCR5380_select(instance, tmp)) {
+						/* OK or bad target */
 						local_irq_disable();
 						hostdata->retain_dma_intr--;
-						/* release if target did not response! */
 						maybe_release_dma_irq(instance);
 						local_irq_restore(flags);
-						break;
 					} else {
+						/* Need to retry */
 						local_irq_disable();
 						LIST(tmp, hostdata->issue_queue);
 						SET_NEXT(tmp, hostdata->issue_queue);
@@ -1157,9 +1157,9 @@ static void NCR5380_main(struct work_str
 						local_irq_restore(flags);
 						dprintk(NDEBUG_MAIN, "scsi%d: main(): select() failed, "
 							    "returned to issue_queue\n", HOSTNO);
-						if (hostdata->connected)
-							break;
 					}
+					if (hostdata->connected)
+						break;
 				} /* if target/lun/target queue is not busy */
 			} /* for issue_queue */
 		} /* if (!hostdata->connected) */

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

* [PATCH 17/71] ncr5380: Keep BSY asserted when entering SELECTION phase
  2015-11-18  8:34 ` Finn Thain
@ 2015-11-18  8:35   ` Finn Thain
  -1 siblings, 0 replies; 268+ messages in thread
From: Finn Thain @ 2015-11-18  8:35 UTC (permalink / raw)
  To: James E.J. Bottomley, Michael Schmitz, linux-m68k, linux-scsi,
	linux-kernel

[-- Attachment #1: ncr5380-assert-BSY-during-selection --]
[-- Type: text/plain, Size: 2294 bytes --]

NCR5380.c is not compliant with the SCSI-2 standard (at least, not with
the draft revision 10L that I have to refer to). The selection algorithm
in atari_NCR5380.c is correct, so use that.

Signed-off-by: Finn Thain <fthain@telegraphics.com.au>

---

The NCR 5380 Family datasheet has a flow chart to support this. Please see
http://pdf.datasheetarchive.com/indexerfiles/Scans-001/Scans-0031883.pdf

This is another old bug fix that was unfortunately never applied to the
original NCR5380.c core driver.

---
 drivers/scsi/NCR5380.c       |    8 +++++++-
 drivers/scsi/atari_NCR5380.c |    7 ++++---
 2 files changed, 11 insertions(+), 4 deletions(-)

Index: linux/drivers/scsi/NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/NCR5380.c	2015-11-18 19:33:23.000000000 +1100
+++ linux/drivers/scsi/NCR5380.c	2015-11-18 19:33:24.000000000 +1100
@@ -1236,7 +1236,13 @@ static int NCR5380_select(struct Scsi_Ho
 		dprintk(NDEBUG_ARBITRATION, "scsi%d : lost arbitration, deasserting MR_ARBITRATE\n", instance->host_no);
 		return -1;
 	}
-	NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_SEL);
+
+	/* 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);
 
 	if (!(hostdata->flags & FLAG_DTC3181E) &&
 	    /* RvC: DTC3181E has some trouble with this
Index: linux/drivers/scsi/atari_NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/atari_NCR5380.c	2015-11-18 19:33:23.000000000 +1100
+++ linux/drivers/scsi/atari_NCR5380.c	2015-11-18 19:33:24.000000000 +1100
@@ -1480,9 +1480,10 @@ static int NCR5380_select(struct Scsi_Ho
 		return -1;
 	}
 
-	/* 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) */
+	/* 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);
 



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

* [PATCH 17/71] ncr5380: Keep BSY asserted when entering SELECTION phase
@ 2015-11-18  8:35   ` Finn Thain
  0 siblings, 0 replies; 268+ messages in thread
From: Finn Thain @ 2015-11-18  8:35 UTC (permalink / raw)
  To: James E.J. Bottomley, Michael Schmitz, linux-m68k, linux-scsi,
	linux-kernel

[-- Attachment #1: ncr5380-assert-BSY-during-selection --]
[-- Type: text/plain, Size: 2292 bytes --]

NCR5380.c is not compliant with the SCSI-2 standard (at least, not with
the draft revision 10L that I have to refer to). The selection algorithm
in atari_NCR5380.c is correct, so use that.

Signed-off-by: Finn Thain <fthain@telegraphics.com.au>

---

The NCR 5380 Family datasheet has a flow chart to support this. Please see
http://pdf.datasheetarchive.com/indexerfiles/Scans-001/Scans-0031883.pdf

This is another old bug fix that was unfortunately never applied to the
original NCR5380.c core driver.

---
 drivers/scsi/NCR5380.c       |    8 +++++++-
 drivers/scsi/atari_NCR5380.c |    7 ++++---
 2 files changed, 11 insertions(+), 4 deletions(-)

Index: linux/drivers/scsi/NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/NCR5380.c	2015-11-18 19:33:23.000000000 +1100
+++ linux/drivers/scsi/NCR5380.c	2015-11-18 19:33:24.000000000 +1100
@@ -1236,7 +1236,13 @@ static int NCR5380_select(struct Scsi_Ho
 		dprintk(NDEBUG_ARBITRATION, "scsi%d : lost arbitration, deasserting MR_ARBITRATE\n", instance->host_no);
 		return -1;
 	}
-	NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_SEL);
+
+	/* 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);
 
 	if (!(hostdata->flags & FLAG_DTC3181E) &&
 	    /* RvC: DTC3181E has some trouble with this
Index: linux/drivers/scsi/atari_NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/atari_NCR5380.c	2015-11-18 19:33:23.000000000 +1100
+++ linux/drivers/scsi/atari_NCR5380.c	2015-11-18 19:33:24.000000000 +1100
@@ -1480,9 +1480,10 @@ static int NCR5380_select(struct Scsi_Ho
 		return -1;
 	}
 
-	/* 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) */
+	/* 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);
 

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

* [PATCH 18/71] ncr5380: Eliminate USLEEP_WAITLONG delay
  2015-11-18  8:34 ` Finn Thain
@ 2015-11-18  8:35   ` Finn Thain
  -1 siblings, 0 replies; 268+ messages in thread
From: Finn Thain @ 2015-11-18  8:35 UTC (permalink / raw)
  To: James E.J. Bottomley, Michael Schmitz, linux-m68k, linux-scsi,
	linux-kernel

[-- Attachment #1: ncr5380-eliminate-USLEEP_WAITLONG --]
[-- Type: text/plain, Size: 4555 bytes --]

Linux 2.1.105 introduced the USLEEP_WAITLONG delay, apparently "needed for
Mustek scanners". It is intended to stall the issue queue for 5 seconds.
There are a number of problems with this.

1. Only g_NCR5380 enables the delay, which implies that the other five
   drivers using the NCR5380.c core driver remain incompatible with
   Mustek scanners.

2. The delay is not implemented by atari_NCR5380.c, which is problematic
   for re-unifying the two core driver forks.

3. The delay is implemented using NCR5380_set_timer() which makes it
   unreliable. A new command queued by the mid-layer cancels the delay.

4. The delay is applied indiscriminately in several situations in which
   NCR5380_select() returns -1. These are-- reselection by the target,
   failure of the target to assert BSY, and failure of the target to
   assert REQ. It's clear from the comments that USLEEP_WAITLONG is not
   relevant to the reselection case. And reportedly, these scanners do
   not disconnect.

5. atari_NCR5380.c was forked before Linux 2.1.105, so it was spared some
   of the damage done to NCR5380.c. In this case, the atari_NCR5380.c core
   driver was more standard-compliant and may not have needed any
   workaround like the USLEEP_WAITLONG kludge. The compliance issue was
   addressed in the previous patch.

If these scanners still don't work, we need a better solution. Retrying
selection until EH aborts a command offers equivalent robustness. Bugs in
the existing driver prevent EH working correctly but this is addressed in
a subsequent patch. Remove USLEEP_WAITLONG.

Signed-off-by: Finn Thain <fthain@telegraphics.com.au>

---
 drivers/scsi/NCR5380.c   |   19 +++++--------------
 drivers/scsi/g_NCR5380.c |    1 -
 2 files changed, 5 insertions(+), 15 deletions(-)

Index: linux/drivers/scsi/NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/NCR5380.c	2015-11-18 19:33:24.000000000 +1100
+++ linux/drivers/scsi/NCR5380.c	2015-11-18 19:33:25.000000000 +1100
@@ -468,10 +468,6 @@ static void NCR5380_print_phase(struct S
 #ifndef USLEEP_POLL
 #define USLEEP_POLL msecs_to_jiffies(200)
 #endif
-#ifndef USLEEP_WAITLONG
-/* RvC: (reasonable time to wait on select error) */
-#define USLEEP_WAITLONG USLEEP_SLEEP
-#endif
 
 /* 
  * Function : int should_disconnect (unsigned char cmd)
@@ -619,8 +615,8 @@ static void prepare_info(struct Scsi_Hos
 	         "can_queue %d, cmd_per_lun %d, "
 	         "sg_tablesize %d, this_id %d, "
 	         "flags { %s%s%s%s}, "
-#if defined(USLEEP_POLL) && defined(USLEEP_WAITLONG)
-		 "USLEEP_POLL %lu, USLEEP_WAITLONG %lu, "
+#if defined(USLEEP_POLL) && defined(USLEEP_SLEEP)
+		 "USLEEP_POLL %lu, USLEEP_SLEEP %lu, "
 #endif
 	         "options { %s} ",
 	         instance->hostt->name, instance->io_port, instance->n_io_port,
@@ -631,8 +627,8 @@ static void prepare_info(struct Scsi_Hos
 	         hostdata->flags & FLAG_DTC3181E      ? "DTC3181E "      : "",
 	         hostdata->flags & FLAG_NO_PSEUDO_DMA ? "NO_PSEUDO_DMA " : "",
 	         hostdata->flags & FLAG_TOSHIBA_DELAY ? "TOSHIBA_DELAY "  : "",
-#if defined(USLEEP_POLL) && defined(USLEEP_WAITLONG)
-	         USLEEP_POLL, USLEEP_WAITLONG,
+#if defined(USLEEP_POLL) && defined(USLEEP_SLEEP)
+	         USLEEP_POLL, USLEEP_SLEEP,
 #endif
 #ifdef AUTOPROBE_IRQ
 	         "AUTOPROBE_IRQ "
@@ -1030,15 +1026,10 @@ static void NCR5380_main(struct work_str
 			if (!NCR5380_select(instance, tmp)) {
 				/* OK or bad target */
 			} else {
-				/* RvC: device failed, so we wait a long time
-				   this is needed for Mustek scanners, that
-				   do not respond to commands immediately
-				   after a scan */
-				printk(KERN_DEBUG "scsi%d: device %d did not respond in time\n", instance->host_no, tmp->device->id);
 				LIST(tmp, hostdata->issue_queue);
 				tmp->host_scribble = (unsigned char *) hostdata->issue_queue;
 				hostdata->issue_queue = tmp;
-				NCR5380_set_timer(hostdata, USLEEP_WAITLONG);
+				done = 0;
 			}
 		}	/* if hostdata->selecting */
 		if (hostdata->connected
Index: linux/drivers/scsi/g_NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/g_NCR5380.c	2015-11-18 19:33:12.000000000 +1100
+++ linux/drivers/scsi/g_NCR5380.c	2015-11-18 19:33:25.000000000 +1100
@@ -59,7 +59,6 @@
 /* settings for DTC3181E card with only Mustek scanner attached */
 #define USLEEP_POLL	msecs_to_jiffies(10)
 #define USLEEP_SLEEP	msecs_to_jiffies(200)
-#define USLEEP_WAITLONG	msecs_to_jiffies(5000)
 
 #define AUTOPROBE_IRQ
 



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

* [PATCH 18/71] ncr5380: Eliminate USLEEP_WAITLONG delay
@ 2015-11-18  8:35   ` Finn Thain
  0 siblings, 0 replies; 268+ messages in thread
From: Finn Thain @ 2015-11-18  8:35 UTC (permalink / raw)
  To: James E.J. Bottomley, Michael Schmitz, linux-m68k, linux-scsi,
	linux-kernel

[-- Attachment #1: ncr5380-eliminate-USLEEP_WAITLONG --]
[-- Type: text/plain, Size: 4555 bytes --]

Linux 2.1.105 introduced the USLEEP_WAITLONG delay, apparently "needed for
Mustek scanners". It is intended to stall the issue queue for 5 seconds.
There are a number of problems with this.

1. Only g_NCR5380 enables the delay, which implies that the other five
   drivers using the NCR5380.c core driver remain incompatible with
   Mustek scanners.

2. The delay is not implemented by atari_NCR5380.c, which is problematic
   for re-unifying the two core driver forks.

3. The delay is implemented using NCR5380_set_timer() which makes it
   unreliable. A new command queued by the mid-layer cancels the delay.

4. The delay is applied indiscriminately in several situations in which
   NCR5380_select() returns -1. These are-- reselection by the target,
   failure of the target to assert BSY, and failure of the target to
   assert REQ. It's clear from the comments that USLEEP_WAITLONG is not
   relevant to the reselection case. And reportedly, these scanners do
   not disconnect.

5. atari_NCR5380.c was forked before Linux 2.1.105, so it was spared some
   of the damage done to NCR5380.c. In this case, the atari_NCR5380.c core
   driver was more standard-compliant and may not have needed any
   workaround like the USLEEP_WAITLONG kludge. The compliance issue was
   addressed in the previous patch.

If these scanners still don't work, we need a better solution. Retrying
selection until EH aborts a command offers equivalent robustness. Bugs in
the existing driver prevent EH working correctly but this is addressed in
a subsequent patch. Remove USLEEP_WAITLONG.

Signed-off-by: Finn Thain <fthain@telegraphics.com.au>

---
 drivers/scsi/NCR5380.c   |   19 +++++--------------
 drivers/scsi/g_NCR5380.c |    1 -
 2 files changed, 5 insertions(+), 15 deletions(-)

Index: linux/drivers/scsi/NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/NCR5380.c	2015-11-18 19:33:24.000000000 +1100
+++ linux/drivers/scsi/NCR5380.c	2015-11-18 19:33:25.000000000 +1100
@@ -468,10 +468,6 @@ static void NCR5380_print_phase(struct S
 #ifndef USLEEP_POLL
 #define USLEEP_POLL msecs_to_jiffies(200)
 #endif
-#ifndef USLEEP_WAITLONG
-/* RvC: (reasonable time to wait on select error) */
-#define USLEEP_WAITLONG USLEEP_SLEEP
-#endif
 
 /* 
  * Function : int should_disconnect (unsigned char cmd)
@@ -619,8 +615,8 @@ static void prepare_info(struct Scsi_Hos
 	         "can_queue %d, cmd_per_lun %d, "
 	         "sg_tablesize %d, this_id %d, "
 	         "flags { %s%s%s%s}, "
-#if defined(USLEEP_POLL) && defined(USLEEP_WAITLONG)
-		 "USLEEP_POLL %lu, USLEEP_WAITLONG %lu, "
+#if defined(USLEEP_POLL) && defined(USLEEP_SLEEP)
+		 "USLEEP_POLL %lu, USLEEP_SLEEP %lu, "
 #endif
 	         "options { %s} ",
 	         instance->hostt->name, instance->io_port, instance->n_io_port,
@@ -631,8 +627,8 @@ static void prepare_info(struct Scsi_Hos
 	         hostdata->flags & FLAG_DTC3181E      ? "DTC3181E "      : "",
 	         hostdata->flags & FLAG_NO_PSEUDO_DMA ? "NO_PSEUDO_DMA " : "",
 	         hostdata->flags & FLAG_TOSHIBA_DELAY ? "TOSHIBA_DELAY "  : "",
-#if defined(USLEEP_POLL) && defined(USLEEP_WAITLONG)
-	         USLEEP_POLL, USLEEP_WAITLONG,
+#if defined(USLEEP_POLL) && defined(USLEEP_SLEEP)
+	         USLEEP_POLL, USLEEP_SLEEP,
 #endif
 #ifdef AUTOPROBE_IRQ
 	         "AUTOPROBE_IRQ "
@@ -1030,15 +1026,10 @@ static void NCR5380_main(struct work_str
 			if (!NCR5380_select(instance, tmp)) {
 				/* OK or bad target */
 			} else {
-				/* RvC: device failed, so we wait a long time
-				   this is needed for Mustek scanners, that
-				   do not respond to commands immediately
-				   after a scan */
-				printk(KERN_DEBUG "scsi%d: device %d did not respond in time\n", instance->host_no, tmp->device->id);
 				LIST(tmp, hostdata->issue_queue);
 				tmp->host_scribble = (unsigned char *) hostdata->issue_queue;
 				hostdata->issue_queue = tmp;
-				NCR5380_set_timer(hostdata, USLEEP_WAITLONG);
+				done = 0;
 			}
 		}	/* if hostdata->selecting */
 		if (hostdata->connected
Index: linux/drivers/scsi/g_NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/g_NCR5380.c	2015-11-18 19:33:12.000000000 +1100
+++ linux/drivers/scsi/g_NCR5380.c	2015-11-18 19:33:25.000000000 +1100
@@ -59,7 +59,6 @@
 /* settings for DTC3181E card with only Mustek scanner attached */
 #define USLEEP_POLL	msecs_to_jiffies(10)
 #define USLEEP_SLEEP	msecs_to_jiffies(200)
-#define USLEEP_WAITLONG	msecs_to_jiffies(5000)
 
 #define AUTOPROBE_IRQ
 



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

* [PATCH 19/71] ncr5380: Cleanup bogus {request,release}_region() calls
  2015-11-18  8:34 ` Finn Thain
  (?)
@ 2015-11-18  8:35   ` Finn Thain
  -1 siblings, 0 replies; 268+ messages in thread
From: Finn Thain @ 2015-11-18  8:35 UTC (permalink / raw)
  To: James E.J. Bottomley, Michael Schmitz, linux-m68k, linux-scsi,
	linux-kernel, Russell King, linux-arm-kernel

[-- Attachment #1: ncr5380-cleanup-request_region-release_region --]
[-- Type: text/plain, Size: 2832 bytes --]

Commit 8b801ead3d7a ("[ARM] rpc: update Acorn SCSI drivers to modern ecard
interfaces") neglected to remove a request_region() call in cumana_1.c.

Commit eda32612f7b2 ("[PATCH] give all LLDD driver a ->release method") in
history/history.git added some pointless release_region() calls in dtc.c,
pas16.c and t128.c.

Fix these issues.

Signed-off-by: Finn Thain <fthain@telegraphics.com.au>

---
 drivers/scsi/arm/cumana_1.c |    6 ------
 drivers/scsi/dtc.c          |    2 --
 drivers/scsi/pas16.c        |    2 --
 drivers/scsi/t128.c         |    2 --
 4 files changed, 12 deletions(-)

Index: linux/drivers/scsi/arm/cumana_1.c
===================================================================
--- linux.orig/drivers/scsi/arm/cumana_1.c	2015-11-18 19:33:10.000000000 +1100
+++ linux/drivers/scsi/arm/cumana_1.c	2015-11-18 19:33:26.000000000 +1100
@@ -245,12 +245,6 @@ static int cumanascsi1_probe(struct expa
         priv(host)->ctrl = 0;
         writeb(0, priv(host)->base + CTRL);
 
-	host->n_io_port = 255;
-	if (!(request_region(host->io_port, host->n_io_port, "CumanaSCSI-1"))) {
-		ret = -EBUSY;
-		goto out_unmap;
-	}
-
 	ret = request_irq(host->irq, cumanascsi_intr, 0,
 			  "CumanaSCSI-1", host);
 	if (ret) {
Index: linux/drivers/scsi/dtc.c
===================================================================
--- linux.orig/drivers/scsi/dtc.c	2015-11-18 19:33:10.000000000 +1100
+++ linux/drivers/scsi/dtc.c	2015-11-18 19:33:26.000000000 +1100
@@ -423,8 +423,6 @@ static int dtc_release(struct Scsi_Host
 	if (shost->irq != NO_IRQ)
 		free_irq(shost->irq, shost);
 	NCR5380_exit(shost);
-	if (shost->io_port && shost->n_io_port)
-		release_region(shost->io_port, shost->n_io_port);
 	scsi_unregister(shost);
 	iounmap(hostdata->base);
 	return 0;
Index: linux/drivers/scsi/pas16.c
===================================================================
--- linux.orig/drivers/scsi/pas16.c	2015-11-18 19:33:10.000000000 +1100
+++ linux/drivers/scsi/pas16.c	2015-11-18 19:33:26.000000000 +1100
@@ -540,8 +540,6 @@ static int pas16_release(struct Scsi_Hos
 	if (shost->irq != NO_IRQ)
 		free_irq(shost->irq, shost);
 	NCR5380_exit(shost);
-	if (shost->io_port && shost->n_io_port)
-		release_region(shost->io_port, shost->n_io_port);
 	scsi_unregister(shost);
 	return 0;
 }
Index: linux/drivers/scsi/t128.c
===================================================================
--- linux.orig/drivers/scsi/t128.c	2015-11-18 19:33:10.000000000 +1100
+++ linux/drivers/scsi/t128.c	2015-11-18 19:33:26.000000000 +1100
@@ -255,8 +255,6 @@ static int t128_release(struct Scsi_Host
 	if (shost->irq != NO_IRQ)
 		free_irq(shost->irq, shost);
 	NCR5380_exit(shost);
-	if (shost->io_port && shost->n_io_port)
-		release_region(shost->io_port, shost->n_io_port);
 	scsi_unregister(shost);
 	iounmap(hostdata->base);
 	return 0;



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

* [PATCH 19/71] ncr5380: Cleanup bogus {request,release}_region() calls
@ 2015-11-18  8:35   ` Finn Thain
  0 siblings, 0 replies; 268+ messages in thread
From: Finn Thain @ 2015-11-18  8:35 UTC (permalink / raw)
  To: James E.J. Bottomley, Michael Schmitz, linux-m68k, linux-scsi,
	linux-kernel, Russell King, linux-arm-kernel

[-- Attachment #1: ncr5380-cleanup-request_region-release_region --]
[-- Type: text/plain, Size: 2830 bytes --]

Commit 8b801ead3d7a ("[ARM] rpc: update Acorn SCSI drivers to modern ecard
interfaces") neglected to remove a request_region() call in cumana_1.c.

Commit eda32612f7b2 ("[PATCH] give all LLDD driver a ->release method") in
history/history.git added some pointless release_region() calls in dtc.c,
pas16.c and t128.c.

Fix these issues.

Signed-off-by: Finn Thain <fthain@telegraphics.com.au>

---
 drivers/scsi/arm/cumana_1.c |    6 ------
 drivers/scsi/dtc.c          |    2 --
 drivers/scsi/pas16.c        |    2 --
 drivers/scsi/t128.c         |    2 --
 4 files changed, 12 deletions(-)

Index: linux/drivers/scsi/arm/cumana_1.c
===================================================================
--- linux.orig/drivers/scsi/arm/cumana_1.c	2015-11-18 19:33:10.000000000 +1100
+++ linux/drivers/scsi/arm/cumana_1.c	2015-11-18 19:33:26.000000000 +1100
@@ -245,12 +245,6 @@ static int cumanascsi1_probe(struct expa
         priv(host)->ctrl = 0;
         writeb(0, priv(host)->base + CTRL);
 
-	host->n_io_port = 255;
-	if (!(request_region(host->io_port, host->n_io_port, "CumanaSCSI-1"))) {
-		ret = -EBUSY;
-		goto out_unmap;
-	}
-
 	ret = request_irq(host->irq, cumanascsi_intr, 0,
 			  "CumanaSCSI-1", host);
 	if (ret) {
Index: linux/drivers/scsi/dtc.c
===================================================================
--- linux.orig/drivers/scsi/dtc.c	2015-11-18 19:33:10.000000000 +1100
+++ linux/drivers/scsi/dtc.c	2015-11-18 19:33:26.000000000 +1100
@@ -423,8 +423,6 @@ static int dtc_release(struct Scsi_Host
 	if (shost->irq != NO_IRQ)
 		free_irq(shost->irq, shost);
 	NCR5380_exit(shost);
-	if (shost->io_port && shost->n_io_port)
-		release_region(shost->io_port, shost->n_io_port);
 	scsi_unregister(shost);
 	iounmap(hostdata->base);
 	return 0;
Index: linux/drivers/scsi/pas16.c
===================================================================
--- linux.orig/drivers/scsi/pas16.c	2015-11-18 19:33:10.000000000 +1100
+++ linux/drivers/scsi/pas16.c	2015-11-18 19:33:26.000000000 +1100
@@ -540,8 +540,6 @@ static int pas16_release(struct Scsi_Hos
 	if (shost->irq != NO_IRQ)
 		free_irq(shost->irq, shost);
 	NCR5380_exit(shost);
-	if (shost->io_port && shost->n_io_port)
-		release_region(shost->io_port, shost->n_io_port);
 	scsi_unregister(shost);
 	return 0;
 }
Index: linux/drivers/scsi/t128.c
===================================================================
--- linux.orig/drivers/scsi/t128.c	2015-11-18 19:33:10.000000000 +1100
+++ linux/drivers/scsi/t128.c	2015-11-18 19:33:26.000000000 +1100
@@ -255,8 +255,6 @@ static int t128_release(struct Scsi_Host
 	if (shost->irq != NO_IRQ)
 		free_irq(shost->irq, shost);
 	NCR5380_exit(shost);
-	if (shost->io_port && shost->n_io_port)
-		release_region(shost->io_port, shost->n_io_port);
 	scsi_unregister(shost);
 	iounmap(hostdata->base);
 	return 0;

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

* [PATCH 19/71] ncr5380: Cleanup bogus {request, release}_region() calls
@ 2015-11-18  8:35   ` Finn Thain
  0 siblings, 0 replies; 268+ messages in thread
From: Finn Thain @ 2015-11-18  8:35 UTC (permalink / raw)
  To: linux-arm-kernel

An embedded and charset-unspecified text was scrubbed...
Name: ncr5380-cleanup-request_region-release_region
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20151118/f1c07ae0/attachment.ksh>

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

* [PATCH 20/71] ncr5380: Introduce unbound workqueue
  2015-11-18  8:34 ` Finn Thain
  (?)
@ 2015-11-18  8:35   ` Finn Thain
  -1 siblings, 0 replies; 268+ messages in thread
From: Finn Thain @ 2015-11-18  8:35 UTC (permalink / raw)
  To: James E.J. Bottomley, Michael Schmitz, linux-m68k, linux-scsi,
	linux-kernel, Russell King, linux-arm-kernel

[-- Attachment #1: ncr5380-new-workqueue --]
[-- Type: text/plain, Size: 14735 bytes --]

Allocate a work queue that will permit busy waiting and sleeping. This
means NCR5380_init() can potentially fail, so add this error path.

Signed-off-by: Finn Thain <fthain@telegraphics.com.au>

---

In subsequent patches, the work function adopts this work queue so it
can sleep while polling, which allows the removal of some flawed and
complicated code in NCR5380_select() in NCR5380.c.

---
 drivers/scsi/NCR5380.c       |   15 +++++++++++----
 drivers/scsi/NCR5380.h       |    1 +
 drivers/scsi/arm/cumana_1.c  |    8 ++++++--
 drivers/scsi/arm/oak.c       |    8 ++++++--
 drivers/scsi/atari_NCR5380.c |    8 +++++++-
 drivers/scsi/atari_scsi.c    |    5 ++++-
 drivers/scsi/dmx3191d.c      |   17 +++++++++++------
 drivers/scsi/dtc.c           |   11 +++++++++--
 drivers/scsi/g_NCR5380.c     |   31 +++++++++++++++----------------
 drivers/scsi/mac_scsi.c      |    5 ++++-
 drivers/scsi/pas16.c         |   10 ++++++++--
 drivers/scsi/sun3_scsi.c     |    5 ++++-
 drivers/scsi/t128.c          |   13 ++++++++++---
 13 files changed, 96 insertions(+), 41 deletions(-)

Index: linux/drivers/scsi/NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/NCR5380.c	2015-11-18 19:33:25.000000000 +1100
+++ linux/drivers/scsi/NCR5380.c	2015-11-18 19:33:27.000000000 +1100
@@ -514,7 +514,7 @@ static int should_disconnect(unsigned ch
 static void NCR5380_set_timer(struct NCR5380_hostdata *hostdata, unsigned long timeout)
 {
 	hostdata->time_expires = jiffies + timeout;
-	schedule_delayed_work(&hostdata->coroutine, timeout);
+	queue_delayed_work(hostdata->work_q, &hostdata->coroutine, timeout);
 }
 
 
@@ -791,7 +791,12 @@ static int NCR5380_init(struct Scsi_Host
 	hostdata->disconnected_queue = NULL;
 	
 	INIT_DELAYED_WORK(&hostdata->coroutine, NCR5380_main);
-	
+	hostdata->work_q = alloc_workqueue("ncr5380_%d",
+	                        WQ_CPU_INTENSIVE | WQ_UNBOUND | WQ_MEM_RECLAIM,
+	                        1, instance->host_no);
+	if (!hostdata->work_q)
+		return -ENOMEM;
+
 	/* The CHECK code seems to break the 53C400. Will check it later maybe */
 	if (flags & FLAG_NCR53C400)
 		hostdata->flags = FLAG_HAS_LAST_BYTE_SENT | flags;
@@ -872,6 +877,7 @@ static void NCR5380_exit(struct Scsi_Hos
 	struct NCR5380_hostdata *hostdata = (struct NCR5380_hostdata *) instance->hostdata;
 
 	cancel_delayed_work_sync(&hostdata->coroutine);
+	destroy_workqueue(hostdata->work_q);
 }
 
 /**
@@ -932,7 +938,7 @@ static int NCR5380_queue_command_lck(str
 
 	/* Run the coroutine if it isn't already running. */
 	/* Kick off command processing */
-	schedule_delayed_work(&hostdata->coroutine, 0);
+	queue_delayed_work(hostdata->work_q, &hostdata->coroutine, 0);
 	return 0;
 }
 
@@ -1128,7 +1134,8 @@ static irqreturn_t NCR5380_intr(int dumm
 		}	/* if BASR_IRQ */
 		spin_unlock_irqrestore(instance->host_lock, flags);
 		if(!done)
-			schedule_delayed_work(&hostdata->coroutine, 0);
+			queue_delayed_work(hostdata->work_q,
+			                   &hostdata->coroutine, 0);
 	} while (!done);
 	return IRQ_HANDLED;
 }
Index: linux/drivers/scsi/NCR5380.h
===================================================================
--- linux.orig/drivers/scsi/NCR5380.h	2015-11-18 19:33:21.000000000 +1100
+++ linux/drivers/scsi/NCR5380.h	2015-11-18 19:33:27.000000000 +1100
@@ -284,6 +284,7 @@ struct NCR5380_hostdata {
 	unsigned spin_max_r;
 	unsigned spin_max_w;
 #endif
+	struct workqueue_struct *work_q;
 };
 
 #ifdef __KERNEL__
Index: linux/drivers/scsi/arm/cumana_1.c
===================================================================
--- linux.orig/drivers/scsi/arm/cumana_1.c	2015-11-18 19:33:26.000000000 +1100
+++ linux/drivers/scsi/arm/cumana_1.c	2015-11-18 19:33:27.000000000 +1100
@@ -238,7 +238,9 @@ static int cumanascsi1_probe(struct expa
 
 	host->irq = ec->irq;
 
-	NCR5380_init(host, 0);
+	ret = NCR5380_init(host, 0);
+	if (ret)
+		goto out_unmap;
 
 	NCR5380_maybe_reset_bus(host);
 
@@ -250,7 +252,7 @@ static int cumanascsi1_probe(struct expa
 	if (ret) {
 		printk("scsi%d: IRQ%d not free: %d\n",
 		    host->host_no, host->irq, ret);
-		goto out_unmap;
+		goto out_exit;
 	}
 
 	ret = scsi_add_host(host, &ec->dev);
@@ -262,6 +264,8 @@ static int cumanascsi1_probe(struct expa
 
  out_free_irq:
 	free_irq(host->irq, host);
+ out_exit:
+	NCR5380_exit(host);
  out_unmap:
 	iounmap(priv(host)->base);
 	iounmap(priv(host)->dma);
Index: linux/drivers/scsi/arm/oak.c
===================================================================
--- linux.orig/drivers/scsi/arm/oak.c	2015-11-18 19:33:10.000000000 +1100
+++ linux/drivers/scsi/arm/oak.c	2015-11-18 19:33:27.000000000 +1100
@@ -143,17 +143,21 @@ static int oakscsi_probe(struct expansio
 	host->irq = NO_IRQ;
 	host->n_io_port = 255;
 
-	NCR5380_init(host, 0);
+	ret = NCR5380_init(host, 0);
+	if (ret)
+		goto out_unmap;
 
 	NCR5380_maybe_reset_bus(host);
 
 	ret = scsi_add_host(host, &ec->dev);
 	if (ret)
-		goto out_unmap;
+		goto out_exit;
 
 	scsi_scan_host(host);
 	goto out;
 
+ out_exit:
+	NCR5380_exit(host);
  out_unmap:
 	iounmap(priv(host)->base);
  unreg:
Index: linux/drivers/scsi/atari_NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/atari_NCR5380.c	2015-11-18 19:33:24.000000000 +1100
+++ linux/drivers/scsi/atari_NCR5380.c	2015-11-18 19:33:27.000000000 +1100
@@ -643,7 +643,7 @@ static inline void queue_main(struct NCR
 		   queue it on the 'immediate' task queue, to be processed
 		   immediately after the current interrupt processing has
 		   finished. */
-		schedule_work(&hostdata->main_task);
+		queue_work(hostdata->work_q, &hostdata->main_task);
 	}
 	/* else: nothing to do: the running NCR5380_main() will pick up
 	   any newly queued command. */
@@ -832,6 +832,11 @@ static int __init NCR5380_init(struct Sc
 	hostdata->flags = flags;
 
 	INIT_WORK(&hostdata->main_task, NCR5380_main);
+	hostdata->work_q = alloc_workqueue("ncr5380_%d",
+	                        WQ_CPU_INTENSIVE | WQ_UNBOUND | WQ_MEM_RECLAIM,
+	                        1, instance->host_no);
+	if (!hostdata->work_q)
+		return -ENOMEM;
 
 	prepare_info(instance);
 
@@ -907,6 +912,7 @@ static void NCR5380_exit(struct Scsi_Hos
 	struct NCR5380_hostdata *hostdata = shost_priv(instance);
 
 	cancel_work_sync(&hostdata->main_task);
+	destroy_workqueue(hostdata->work_q);
 }
 
 /**
Index: linux/drivers/scsi/atari_scsi.c
===================================================================
--- linux.orig/drivers/scsi/atari_scsi.c	2015-11-18 19:33:15.000000000 +1100
+++ linux/drivers/scsi/atari_scsi.c	2015-11-18 19:33:27.000000000 +1100
@@ -885,7 +885,9 @@ static int __init atari_scsi_probe(struc
 #endif
 	host_flags |= setup_toshiba_delay > 0 ? FLAG_TOSHIBA_DELAY : 0;
 
-	NCR5380_init(instance, host_flags);
+	error = NCR5380_init(instance, host_flags);
+	if (error)
+		goto fail_init;
 
 	if (IS_A_TT()) {
 		error = request_irq(instance->irq, scsi_tt_intr, 0,
@@ -947,6 +949,7 @@ fail_host:
 		free_irq(instance->irq, instance);
 fail_irq:
 	NCR5380_exit(instance);
+fail_init:
 	scsi_host_put(instance);
 fail_alloc:
 	if (atari_dma_buffer)
Index: linux/drivers/scsi/dmx3191d.c
===================================================================
--- linux.orig/drivers/scsi/dmx3191d.c	2015-11-18 19:33:10.000000000 +1100
+++ linux/drivers/scsi/dmx3191d.c	2015-11-18 19:33:27.000000000 +1100
@@ -95,7 +95,9 @@ static int dmx3191d_probe_one(struct pci
 	 */
 	shost->irq = NO_IRQ;
 
-	NCR5380_init(shost, FLAG_NO_PSEUDO_DMA | FLAG_DTC3181E);
+	error = NCR5380_init(shost, FLAG_NO_PSEUDO_DMA | FLAG_DTC3181E);
+	if (error)
+		goto out_host_put;
 
 	NCR5380_maybe_reset_bus(shost);
 
@@ -103,11 +105,15 @@ static int dmx3191d_probe_one(struct pci
 
 	error = scsi_add_host(shost, &pdev->dev);
 	if (error)
-		goto out_release_region;
+		goto out_exit;
 
 	scsi_scan_host(shost);
 	return 0;
 
+out_exit:
+	NCR5380_exit(shost);
+out_host_put:
+	scsi_host_put(shost);
  out_release_region:
 	release_region(io, DMX3191D_REGION_LEN);
  out_disable_device:
@@ -119,15 +125,14 @@ static int dmx3191d_probe_one(struct pci
 static void dmx3191d_remove_one(struct pci_dev *pdev)
 {
 	struct Scsi_Host *shost = pci_get_drvdata(pdev);
+	unsigned long io = shost->io_port;
 
 	scsi_remove_host(shost);
 
 	NCR5380_exit(shost);
-
-	release_region(shost->io_port, DMX3191D_REGION_LEN);
-	pci_disable_device(pdev);
-
 	scsi_host_put(shost);
+	release_region(io, DMX3191D_REGION_LEN);
+	pci_disable_device(pdev);
 }
 
 static struct pci_device_id dmx3191d_pci_tbl[] = {
Index: linux/drivers/scsi/dtc.c
===================================================================
--- linux.orig/drivers/scsi/dtc.c	2015-11-18 19:33:26.000000000 +1100
+++ linux/drivers/scsi/dtc.c	2015-11-18 19:33:27.000000000 +1100
@@ -230,12 +230,13 @@ static int __init dtc_detect(struct scsi
 found:
 		instance = scsi_register(tpnt, sizeof(struct NCR5380_hostdata));
 		if (instance == NULL)
-			break;
+			goto out_unmap;
 
 		instance->base = addr;
 		((struct NCR5380_hostdata *)(instance)->hostdata)->base = base;
 
-		NCR5380_init(instance, 0);
+		if (NCR5380_init(instance, 0))
+			goto out_unregister;
 
 		NCR5380_maybe_reset_bus(instance);
 
@@ -275,6 +276,12 @@ found:
 		++count;
 	}
 	return count;
+
+out_unregister:
+	scsi_unregister(instance);
+out_unmap:
+	iounmap(base);
+	return count;
 }
 
 /*
Index: linux/drivers/scsi/g_NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/g_NCR5380.c	2015-11-18 19:33:25.000000000 +1100
+++ linux/drivers/scsi/g_NCR5380.c	2015-11-18 19:33:27.000000000 +1100
@@ -239,9 +239,6 @@ static int __init do_DTC3181E_setup(char
  *	and DTC436(ISAPnP) controllers. If overrides have been set we use
  *	them.
  *
- *	The caller supplied NCR5380_init function is invoked from here, before
- *	the interrupt line is taken.
- *
  *	Locks: none
  */
 
@@ -404,15 +401,8 @@ static int __init generic_NCR5380_detect
 		}
 #endif
 		instance = scsi_register(tpnt, sizeof(struct NCR5380_hostdata));
-		if (instance == NULL) {
-#ifndef SCSI_G_NCR5380_MEM
-			release_region(overrides[current_override].NCR5380_map_name, region_size);
-#else
-			iounmap(iomem);
-			release_mem_region(base, NCR5380_region_size);
-#endif
-			continue;
-		}
+		if (instance == NULL)
+			goto out_release;
 
 #ifndef SCSI_G_NCR5380_MEM
 		instance->io_port = overrides[current_override].NCR5380_map_name;
@@ -429,7 +419,8 @@ static int __init generic_NCR5380_detect
 		((struct NCR5380_hostdata *)instance->hostdata)->iomem = iomem;
 #endif
 
-		NCR5380_init(instance, flags);
+		if (NCR5380_init(instance, flags))
+			goto out_unregister;
 
 		if (overrides[current_override].board == BOARD_NCR53C400)
 			NCR5380_write(C400_CONTROL_STATUS_REG, CSR_BASE);
@@ -461,6 +452,17 @@ static int __init generic_NCR5380_detect
 		++count;
 	}
 	return count;
+
+out_unregister:
+	scsi_unregister(instance);
+out_release:
+#ifndef SCSI_G_NCR5380_MEM
+	release_region(overrides[current_override].NCR5380_map_name, region_size);
+#else
+	iounmap(iomem);
+	release_mem_region(base, NCR5380_region_size);
+#endif
+	return count;
 }
 
 /**
@@ -477,15 +479,12 @@ static int generic_NCR5380_release_resou
 	if (instance->irq != NO_IRQ)
 		free_irq(instance->irq, instance);
 	NCR5380_exit(instance);
-
 #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;
 }
 
Index: linux/drivers/scsi/mac_scsi.c
===================================================================
--- linux.orig/drivers/scsi/mac_scsi.c	2015-11-18 19:33:15.000000000 +1100
+++ linux/drivers/scsi/mac_scsi.c	2015-11-18 19:33:27.000000000 +1100
@@ -382,7 +382,9 @@ static int __init mac_scsi_probe(struct
 #endif
 	host_flags |= setup_toshiba_delay > 0 ? FLAG_TOSHIBA_DELAY : 0;
 
-	NCR5380_init(instance, host_flags);
+	error = NCR5380_init(instance, host_flags);
+	if (error)
+		goto fail_init;
 
 	if (instance->irq != NO_IRQ) {
 		error = request_irq(instance->irq, macscsi_intr, IRQF_SHARED,
@@ -407,6 +409,7 @@ fail_host:
 		free_irq(instance->irq, instance);
 fail_irq:
 	NCR5380_exit(instance);
+fail_init:
 	scsi_host_put(instance);
 	return error;
 }
Index: linux/drivers/scsi/pas16.c
===================================================================
--- linux.orig/drivers/scsi/pas16.c	2015-11-18 19:33:26.000000000 +1100
+++ linux/drivers/scsi/pas16.c	2015-11-18 19:33:27.000000000 +1100
@@ -378,11 +378,12 @@ static int __init pas16_detect(struct sc
 
 	instance = scsi_register (tpnt, sizeof(struct NCR5380_hostdata));
 	if(instance == NULL)
-		break;
+		goto out;
 		
 	instance->io_port = io_port;
 
-	NCR5380_init(instance, 0);
+	if (NCR5380_init(instance, 0))
+		goto out_unregister;
 
 	NCR5380_maybe_reset_bus(instance);
 
@@ -418,6 +419,11 @@ static int __init pas16_detect(struct sc
 	++count;
     }
     return count;
+
+out_unregister:
+	scsi_unregister(instance);
+out:
+	return count;
 }
 
 /*
Index: linux/drivers/scsi/sun3_scsi.c
===================================================================
--- linux.orig/drivers/scsi/sun3_scsi.c	2015-11-18 19:33:15.000000000 +1100
+++ linux/drivers/scsi/sun3_scsi.c	2015-11-18 19:33:27.000000000 +1100
@@ -557,7 +557,9 @@ static int __init sun3_scsi_probe(struct
 	host_flags |= setup_use_tagged_queuing > 0 ? FLAG_TAGGED_QUEUING : 0;
 #endif
 
-	NCR5380_init(instance, host_flags);
+	error = NCR5380_init(instance, host_flags);
+	if (error)
+		goto fail_init;
 
 	error = request_irq(instance->irq, scsi_sun3_intr, 0,
 	                    "NCR5380", instance);
@@ -604,6 +606,7 @@ fail_host:
 		free_irq(instance->irq, instance);
 fail_irq:
 	NCR5380_exit(instance);
+fail_init:
 	scsi_host_put(instance);
 fail_alloc:
 	if (udc_regs)
Index: linux/drivers/scsi/t128.c
===================================================================
--- linux.orig/drivers/scsi/t128.c	2015-11-18 19:33:26.000000000 +1100
+++ linux/drivers/scsi/t128.c	2015-11-18 19:33:27.000000000 +1100
@@ -208,12 +208,13 @@ static int __init t128_detect(struct scs
 found:
 	instance = scsi_register (tpnt, sizeof(struct NCR5380_hostdata));
 	if(instance == NULL)
-		break;
-		
+		goto out_unmap;
+
 	instance->base = base;
 	((struct NCR5380_hostdata *)instance->hostdata)->base = p;
 
-	NCR5380_init(instance, 0);
+	if (NCR5380_init(instance, 0))
+		goto out_unregister;
 
 	NCR5380_maybe_reset_bus(instance);
 
@@ -246,6 +247,12 @@ found:
 	++count;
     }
     return count;
+
+out_unregister:
+	scsi_unregister(instance);
+out_unmap:
+	iounmap(p);
+	return count;
 }
 
 static int t128_release(struct Scsi_Host *shost)



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

* [PATCH 20/71] ncr5380: Introduce unbound workqueue
@ 2015-11-18  8:35   ` Finn Thain
  0 siblings, 0 replies; 268+ messages in thread
From: Finn Thain @ 2015-11-18  8:35 UTC (permalink / raw)
  To: James E.J. Bottomley, Michael Schmitz, linux-m68k, linux-scsi,
	linux-kernel, Russell King, linux-arm-kernel

[-- Attachment #1: ncr5380-new-workqueue --]
[-- Type: text/plain, Size: 14733 bytes --]

Allocate a work queue that will permit busy waiting and sleeping. This
means NCR5380_init() can potentially fail, so add this error path.

Signed-off-by: Finn Thain <fthain@telegraphics.com.au>

---

In subsequent patches, the work function adopts this work queue so it
can sleep while polling, which allows the removal of some flawed and
complicated code in NCR5380_select() in NCR5380.c.

---
 drivers/scsi/NCR5380.c       |   15 +++++++++++----
 drivers/scsi/NCR5380.h       |    1 +
 drivers/scsi/arm/cumana_1.c  |    8 ++++++--
 drivers/scsi/arm/oak.c       |    8 ++++++--
 drivers/scsi/atari_NCR5380.c |    8 +++++++-
 drivers/scsi/atari_scsi.c    |    5 ++++-
 drivers/scsi/dmx3191d.c      |   17 +++++++++++------
 drivers/scsi/dtc.c           |   11 +++++++++--
 drivers/scsi/g_NCR5380.c     |   31 +++++++++++++++----------------
 drivers/scsi/mac_scsi.c      |    5 ++++-
 drivers/scsi/pas16.c         |   10 ++++++++--
 drivers/scsi/sun3_scsi.c     |    5 ++++-
 drivers/scsi/t128.c          |   13 ++++++++++---
 13 files changed, 96 insertions(+), 41 deletions(-)

Index: linux/drivers/scsi/NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/NCR5380.c	2015-11-18 19:33:25.000000000 +1100
+++ linux/drivers/scsi/NCR5380.c	2015-11-18 19:33:27.000000000 +1100
@@ -514,7 +514,7 @@ static int should_disconnect(unsigned ch
 static void NCR5380_set_timer(struct NCR5380_hostdata *hostdata, unsigned long timeout)
 {
 	hostdata->time_expires = jiffies + timeout;
-	schedule_delayed_work(&hostdata->coroutine, timeout);
+	queue_delayed_work(hostdata->work_q, &hostdata->coroutine, timeout);
 }
 
 
@@ -791,7 +791,12 @@ static int NCR5380_init(struct Scsi_Host
 	hostdata->disconnected_queue = NULL;
 	
 	INIT_DELAYED_WORK(&hostdata->coroutine, NCR5380_main);
-	
+	hostdata->work_q = alloc_workqueue("ncr5380_%d",
+	                        WQ_CPU_INTENSIVE | WQ_UNBOUND | WQ_MEM_RECLAIM,
+	                        1, instance->host_no);
+	if (!hostdata->work_q)
+		return -ENOMEM;
+
 	/* The CHECK code seems to break the 53C400. Will check it later maybe */
 	if (flags & FLAG_NCR53C400)
 		hostdata->flags = FLAG_HAS_LAST_BYTE_SENT | flags;
@@ -872,6 +877,7 @@ static void NCR5380_exit(struct Scsi_Hos
 	struct NCR5380_hostdata *hostdata = (struct NCR5380_hostdata *) instance->hostdata;
 
 	cancel_delayed_work_sync(&hostdata->coroutine);
+	destroy_workqueue(hostdata->work_q);
 }
 
 /**
@@ -932,7 +938,7 @@ static int NCR5380_queue_command_lck(str
 
 	/* Run the coroutine if it isn't already running. */
 	/* Kick off command processing */
-	schedule_delayed_work(&hostdata->coroutine, 0);
+	queue_delayed_work(hostdata->work_q, &hostdata->coroutine, 0);
 	return 0;
 }
 
@@ -1128,7 +1134,8 @@ static irqreturn_t NCR5380_intr(int dumm
 		}	/* if BASR_IRQ */
 		spin_unlock_irqrestore(instance->host_lock, flags);
 		if(!done)
-			schedule_delayed_work(&hostdata->coroutine, 0);
+			queue_delayed_work(hostdata->work_q,
+			                   &hostdata->coroutine, 0);
 	} while (!done);
 	return IRQ_HANDLED;
 }
Index: linux/drivers/scsi/NCR5380.h
===================================================================
--- linux.orig/drivers/scsi/NCR5380.h	2015-11-18 19:33:21.000000000 +1100
+++ linux/drivers/scsi/NCR5380.h	2015-11-18 19:33:27.000000000 +1100
@@ -284,6 +284,7 @@ struct NCR5380_hostdata {
 	unsigned spin_max_r;
 	unsigned spin_max_w;
 #endif
+	struct workqueue_struct *work_q;
 };
 
 #ifdef __KERNEL__
Index: linux/drivers/scsi/arm/cumana_1.c
===================================================================
--- linux.orig/drivers/scsi/arm/cumana_1.c	2015-11-18 19:33:26.000000000 +1100
+++ linux/drivers/scsi/arm/cumana_1.c	2015-11-18 19:33:27.000000000 +1100
@@ -238,7 +238,9 @@ static int cumanascsi1_probe(struct expa
 
 	host->irq = ec->irq;
 
-	NCR5380_init(host, 0);
+	ret = NCR5380_init(host, 0);
+	if (ret)
+		goto out_unmap;
 
 	NCR5380_maybe_reset_bus(host);
 
@@ -250,7 +252,7 @@ static int cumanascsi1_probe(struct expa
 	if (ret) {
 		printk("scsi%d: IRQ%d not free: %d\n",
 		    host->host_no, host->irq, ret);
-		goto out_unmap;
+		goto out_exit;
 	}
 
 	ret = scsi_add_host(host, &ec->dev);
@@ -262,6 +264,8 @@ static int cumanascsi1_probe(struct expa
 
  out_free_irq:
 	free_irq(host->irq, host);
+ out_exit:
+	NCR5380_exit(host);
  out_unmap:
 	iounmap(priv(host)->base);
 	iounmap(priv(host)->dma);
Index: linux/drivers/scsi/arm/oak.c
===================================================================
--- linux.orig/drivers/scsi/arm/oak.c	2015-11-18 19:33:10.000000000 +1100
+++ linux/drivers/scsi/arm/oak.c	2015-11-18 19:33:27.000000000 +1100
@@ -143,17 +143,21 @@ static int oakscsi_probe(struct expansio
 	host->irq = NO_IRQ;
 	host->n_io_port = 255;
 
-	NCR5380_init(host, 0);
+	ret = NCR5380_init(host, 0);
+	if (ret)
+		goto out_unmap;
 
 	NCR5380_maybe_reset_bus(host);
 
 	ret = scsi_add_host(host, &ec->dev);
 	if (ret)
-		goto out_unmap;
+		goto out_exit;
 
 	scsi_scan_host(host);
 	goto out;
 
+ out_exit:
+	NCR5380_exit(host);
  out_unmap:
 	iounmap(priv(host)->base);
  unreg:
Index: linux/drivers/scsi/atari_NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/atari_NCR5380.c	2015-11-18 19:33:24.000000000 +1100
+++ linux/drivers/scsi/atari_NCR5380.c	2015-11-18 19:33:27.000000000 +1100
@@ -643,7 +643,7 @@ static inline void queue_main(struct NCR
 		   queue it on the 'immediate' task queue, to be processed
 		   immediately after the current interrupt processing has
 		   finished. */
-		schedule_work(&hostdata->main_task);
+		queue_work(hostdata->work_q, &hostdata->main_task);
 	}
 	/* else: nothing to do: the running NCR5380_main() will pick up
 	   any newly queued command. */
@@ -832,6 +832,11 @@ static int __init NCR5380_init(struct Sc
 	hostdata->flags = flags;
 
 	INIT_WORK(&hostdata->main_task, NCR5380_main);
+	hostdata->work_q = alloc_workqueue("ncr5380_%d",
+	                        WQ_CPU_INTENSIVE | WQ_UNBOUND | WQ_MEM_RECLAIM,
+	                        1, instance->host_no);
+	if (!hostdata->work_q)
+		return -ENOMEM;
 
 	prepare_info(instance);
 
@@ -907,6 +912,7 @@ static void NCR5380_exit(struct Scsi_Hos
 	struct NCR5380_hostdata *hostdata = shost_priv(instance);
 
 	cancel_work_sync(&hostdata->main_task);
+	destroy_workqueue(hostdata->work_q);
 }
 
 /**
Index: linux/drivers/scsi/atari_scsi.c
===================================================================
--- linux.orig/drivers/scsi/atari_scsi.c	2015-11-18 19:33:15.000000000 +1100
+++ linux/drivers/scsi/atari_scsi.c	2015-11-18 19:33:27.000000000 +1100
@@ -885,7 +885,9 @@ static int __init atari_scsi_probe(struc
 #endif
 	host_flags |= setup_toshiba_delay > 0 ? FLAG_TOSHIBA_DELAY : 0;
 
-	NCR5380_init(instance, host_flags);
+	error = NCR5380_init(instance, host_flags);
+	if (error)
+		goto fail_init;
 
 	if (IS_A_TT()) {
 		error = request_irq(instance->irq, scsi_tt_intr, 0,
@@ -947,6 +949,7 @@ fail_host:
 		free_irq(instance->irq, instance);
 fail_irq:
 	NCR5380_exit(instance);
+fail_init:
 	scsi_host_put(instance);
 fail_alloc:
 	if (atari_dma_buffer)
Index: linux/drivers/scsi/dmx3191d.c
===================================================================
--- linux.orig/drivers/scsi/dmx3191d.c	2015-11-18 19:33:10.000000000 +1100
+++ linux/drivers/scsi/dmx3191d.c	2015-11-18 19:33:27.000000000 +1100
@@ -95,7 +95,9 @@ static int dmx3191d_probe_one(struct pci
 	 */
 	shost->irq = NO_IRQ;
 
-	NCR5380_init(shost, FLAG_NO_PSEUDO_DMA | FLAG_DTC3181E);
+	error = NCR5380_init(shost, FLAG_NO_PSEUDO_DMA | FLAG_DTC3181E);
+	if (error)
+		goto out_host_put;
 
 	NCR5380_maybe_reset_bus(shost);
 
@@ -103,11 +105,15 @@ static int dmx3191d_probe_one(struct pci
 
 	error = scsi_add_host(shost, &pdev->dev);
 	if (error)
-		goto out_release_region;
+		goto out_exit;
 
 	scsi_scan_host(shost);
 	return 0;
 
+out_exit:
+	NCR5380_exit(shost);
+out_host_put:
+	scsi_host_put(shost);
  out_release_region:
 	release_region(io, DMX3191D_REGION_LEN);
  out_disable_device:
@@ -119,15 +125,14 @@ static int dmx3191d_probe_one(struct pci
 static void dmx3191d_remove_one(struct pci_dev *pdev)
 {
 	struct Scsi_Host *shost = pci_get_drvdata(pdev);
+	unsigned long io = shost->io_port;
 
 	scsi_remove_host(shost);
 
 	NCR5380_exit(shost);
-
-	release_region(shost->io_port, DMX3191D_REGION_LEN);
-	pci_disable_device(pdev);
-
 	scsi_host_put(shost);
+	release_region(io, DMX3191D_REGION_LEN);
+	pci_disable_device(pdev);
 }
 
 static struct pci_device_id dmx3191d_pci_tbl[] = {
Index: linux/drivers/scsi/dtc.c
===================================================================
--- linux.orig/drivers/scsi/dtc.c	2015-11-18 19:33:26.000000000 +1100
+++ linux/drivers/scsi/dtc.c	2015-11-18 19:33:27.000000000 +1100
@@ -230,12 +230,13 @@ static int __init dtc_detect(struct scsi
 found:
 		instance = scsi_register(tpnt, sizeof(struct NCR5380_hostdata));
 		if (instance == NULL)
-			break;
+			goto out_unmap;
 
 		instance->base = addr;
 		((struct NCR5380_hostdata *)(instance)->hostdata)->base = base;
 
-		NCR5380_init(instance, 0);
+		if (NCR5380_init(instance, 0))
+			goto out_unregister;
 
 		NCR5380_maybe_reset_bus(instance);
 
@@ -275,6 +276,12 @@ found:
 		++count;
 	}
 	return count;
+
+out_unregister:
+	scsi_unregister(instance);
+out_unmap:
+	iounmap(base);
+	return count;
 }
 
 /*
Index: linux/drivers/scsi/g_NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/g_NCR5380.c	2015-11-18 19:33:25.000000000 +1100
+++ linux/drivers/scsi/g_NCR5380.c	2015-11-18 19:33:27.000000000 +1100
@@ -239,9 +239,6 @@ static int __init do_DTC3181E_setup(char
  *	and DTC436(ISAPnP) controllers. If overrides have been set we use
  *	them.
  *
- *	The caller supplied NCR5380_init function is invoked from here, before
- *	the interrupt line is taken.
- *
  *	Locks: none
  */
 
@@ -404,15 +401,8 @@ static int __init generic_NCR5380_detect
 		}
 #endif
 		instance = scsi_register(tpnt, sizeof(struct NCR5380_hostdata));
-		if (instance == NULL) {
-#ifndef SCSI_G_NCR5380_MEM
-			release_region(overrides[current_override].NCR5380_map_name, region_size);
-#else
-			iounmap(iomem);
-			release_mem_region(base, NCR5380_region_size);
-#endif
-			continue;
-		}
+		if (instance == NULL)
+			goto out_release;
 
 #ifndef SCSI_G_NCR5380_MEM
 		instance->io_port = overrides[current_override].NCR5380_map_name;
@@ -429,7 +419,8 @@ static int __init generic_NCR5380_detect
 		((struct NCR5380_hostdata *)instance->hostdata)->iomem = iomem;
 #endif
 
-		NCR5380_init(instance, flags);
+		if (NCR5380_init(instance, flags))
+			goto out_unregister;
 
 		if (overrides[current_override].board == BOARD_NCR53C400)
 			NCR5380_write(C400_CONTROL_STATUS_REG, CSR_BASE);
@@ -461,6 +452,17 @@ static int __init generic_NCR5380_detect
 		++count;
 	}
 	return count;
+
+out_unregister:
+	scsi_unregister(instance);
+out_release:
+#ifndef SCSI_G_NCR5380_MEM
+	release_region(overrides[current_override].NCR5380_map_name, region_size);
+#else
+	iounmap(iomem);
+	release_mem_region(base, NCR5380_region_size);
+#endif
+	return count;
 }
 
 /**
@@ -477,15 +479,12 @@ static int generic_NCR5380_release_resou
 	if (instance->irq != NO_IRQ)
 		free_irq(instance->irq, instance);
 	NCR5380_exit(instance);
-
 #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;
 }
 
Index: linux/drivers/scsi/mac_scsi.c
===================================================================
--- linux.orig/drivers/scsi/mac_scsi.c	2015-11-18 19:33:15.000000000 +1100
+++ linux/drivers/scsi/mac_scsi.c	2015-11-18 19:33:27.000000000 +1100
@@ -382,7 +382,9 @@ static int __init mac_scsi_probe(struct
 #endif
 	host_flags |= setup_toshiba_delay > 0 ? FLAG_TOSHIBA_DELAY : 0;
 
-	NCR5380_init(instance, host_flags);
+	error = NCR5380_init(instance, host_flags);
+	if (error)
+		goto fail_init;
 
 	if (instance->irq != NO_IRQ) {
 		error = request_irq(instance->irq, macscsi_intr, IRQF_SHARED,
@@ -407,6 +409,7 @@ fail_host:
 		free_irq(instance->irq, instance);
 fail_irq:
 	NCR5380_exit(instance);
+fail_init:
 	scsi_host_put(instance);
 	return error;
 }
Index: linux/drivers/scsi/pas16.c
===================================================================
--- linux.orig/drivers/scsi/pas16.c	2015-11-18 19:33:26.000000000 +1100
+++ linux/drivers/scsi/pas16.c	2015-11-18 19:33:27.000000000 +1100
@@ -378,11 +378,12 @@ static int __init pas16_detect(struct sc
 
 	instance = scsi_register (tpnt, sizeof(struct NCR5380_hostdata));
 	if(instance == NULL)
-		break;
+		goto out;
 		
 	instance->io_port = io_port;
 
-	NCR5380_init(instance, 0);
+	if (NCR5380_init(instance, 0))
+		goto out_unregister;
 
 	NCR5380_maybe_reset_bus(instance);
 
@@ -418,6 +419,11 @@ static int __init pas16_detect(struct sc
 	++count;
     }
     return count;
+
+out_unregister:
+	scsi_unregister(instance);
+out:
+	return count;
 }
 
 /*
Index: linux/drivers/scsi/sun3_scsi.c
===================================================================
--- linux.orig/drivers/scsi/sun3_scsi.c	2015-11-18 19:33:15.000000000 +1100
+++ linux/drivers/scsi/sun3_scsi.c	2015-11-18 19:33:27.000000000 +1100
@@ -557,7 +557,9 @@ static int __init sun3_scsi_probe(struct
 	host_flags |= setup_use_tagged_queuing > 0 ? FLAG_TAGGED_QUEUING : 0;
 #endif
 
-	NCR5380_init(instance, host_flags);
+	error = NCR5380_init(instance, host_flags);
+	if (error)
+		goto fail_init;
 
 	error = request_irq(instance->irq, scsi_sun3_intr, 0,
 	                    "NCR5380", instance);
@@ -604,6 +606,7 @@ fail_host:
 		free_irq(instance->irq, instance);
 fail_irq:
 	NCR5380_exit(instance);
+fail_init:
 	scsi_host_put(instance);
 fail_alloc:
 	if (udc_regs)
Index: linux/drivers/scsi/t128.c
===================================================================
--- linux.orig/drivers/scsi/t128.c	2015-11-18 19:33:26.000000000 +1100
+++ linux/drivers/scsi/t128.c	2015-11-18 19:33:27.000000000 +1100
@@ -208,12 +208,13 @@ static int __init t128_detect(struct scs
 found:
 	instance = scsi_register (tpnt, sizeof(struct NCR5380_hostdata));
 	if(instance == NULL)
-		break;
-		
+		goto out_unmap;
+
 	instance->base = base;
 	((struct NCR5380_hostdata *)instance->hostdata)->base = p;
 
-	NCR5380_init(instance, 0);
+	if (NCR5380_init(instance, 0))
+		goto out_unregister;
 
 	NCR5380_maybe_reset_bus(instance);
 
@@ -246,6 +247,12 @@ found:
 	++count;
     }
     return count;
+
+out_unregister:
+	scsi_unregister(instance);
+out_unmap:
+	iounmap(p);
+	return count;
 }
 
 static int t128_release(struct Scsi_Host *shost)

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

* [PATCH 20/71] ncr5380: Introduce unbound workqueue
@ 2015-11-18  8:35   ` Finn Thain
  0 siblings, 0 replies; 268+ messages in thread
From: Finn Thain @ 2015-11-18  8:35 UTC (permalink / raw)
  To: linux-arm-kernel

An embedded and charset-unspecified text was scrubbed...
Name: ncr5380-new-workqueue
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20151118/3cc1d646/attachment.ksh>

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

* [PATCH 21/71] ncr5380: Sleep when polling, if possible
  2015-11-18  8:34 ` Finn Thain
@ 2015-11-18  8:35   ` Finn Thain
  -1 siblings, 0 replies; 268+ messages in thread
From: Finn Thain @ 2015-11-18  8:35 UTC (permalink / raw)
  To: James E.J. Bottomley, Michael Schmitz, linux-m68k, linux-scsi,
	linux-kernel

[-- Attachment #1: ncr5380-sleep-when-polling --]
[-- Type: text/plain, Size: 5535 bytes --]

When in process context, sleep during polling if doing so won't add
significant latency. In interrupt context or if the lock is held, poll
briefly then give up. Keep both core drivers in sync.

Signed-off-by: Finn Thain <fthain@telegraphics.com.au>

---
 drivers/scsi/NCR5380.c       |   73 +++++++++++++++++++++++++------------------
 drivers/scsi/atari_NCR5380.c |   58 +++++++++++++++++++++-------------
 2 files changed, 79 insertions(+), 52 deletions(-)

Index: linux/drivers/scsi/NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/NCR5380.c	2015-11-18 19:33:27.000000000 +1100
+++ linux/drivers/scsi/NCR5380.c	2015-11-18 19:33:31.000000000 +1100
@@ -293,44 +293,57 @@ static inline void initialize_SCp(struct
 }
 
 /**
- *	NCR5380_poll_politely	-	wait for NCR5380 status bits
- *	@instance: controller to poll
- *	@reg: 5380 register to poll
- *	@bit: Bitmask to check
- *	@val: Value required to exit
+ * NCR5380_poll_politely - wait for chip register value
+ * @instance: controller to poll
+ * @reg: 5380 register to poll
+ * @bit: Bitmask to check
+ * @val: Value required to exit
+ * @wait: Time-out in jiffies
  *
- *	Polls the NCR5380 in a reasonably efficient manner waiting for
- *	an event to occur, after a short quick poll we begin giving the
- *	CPU back in non IRQ contexts
+ * 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 the value of the register or a negative error code.
+ * Returns 0 if event occurred otherwise -ETIMEDOUT.
  */
- 
-static int NCR5380_poll_politely(struct Scsi_Host *instance, int reg, int bit, int val, int t)
+
+static int NCR5380_poll_politely(struct Scsi_Host *instance,
+                                 int reg, int bit, int val, int wait)
 {
-	int n = 500;		/* At about 8uS a cycle for the cpu access */
-	unsigned long end = jiffies + t;
-	int r;
-
-	while( n-- > 0)
-	{
-		r = NCR5380_read(reg);
-		if((r & bit) == val)
+	unsigned long start = jiffies;
+	unsigned long n;
+
+	/* Busy-wait for up to 1 jiffy */
+	n = loops_per_jiffy;
+	do {
+		if ((NCR5380_read(reg) & bit) == val)
 			return 0;
 		cpu_relax();
-	}
-	
-	/* t time yet ? */
-	while(time_before(jiffies, end))
-	{
-		r = NCR5380_read(reg);
-		if((r & bit) == val)
+	} while (--n > 0);
+
+	if (--wait <= 0)
+		return -ETIMEDOUT;
+
+	/* Busy-wait for up to 20 ms */
+	n = min(20000U, jiffies_to_usecs(wait));
+	do {
+		udelay(1);
+		if ((NCR5380_read(reg) & bit) == val)
+			return 0;
+		cpu_relax();
+	} while (--n > 0);
+
+	if (irqs_disabled() || in_interrupt())
+		return -ETIMEDOUT;
+
+	/* Repeatedly sleep for 1 ms until deadline */
+	while (time_is_after_jiffies(start + wait)) {
+		schedule_timeout_uninterruptible(1);
+		if ((NCR5380_read(reg) & bit) == val)
 			return 0;
-		if(!in_interrupt())
-			cond_resched();
-		else
-			cpu_relax();
 	}
+
 	return -ETIMEDOUT;
 }
 
Index: linux/drivers/scsi/atari_NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/atari_NCR5380.c	2015-11-18 19:33:27.000000000 +1100
+++ linux/drivers/scsi/atari_NCR5380.c	2015-11-18 19:33:31.000000000 +1100
@@ -479,43 +479,57 @@ static inline void initialize_SCp(struct
 }
 
 /**
- * NCR5380_poll_politely - wait for NCR5380 status bits
+ * NCR5380_poll_politely - wait for chip register value
  * @instance: controller to poll
  * @reg: 5380 register to poll
  * @bit: Bitmask to check
  * @val: Value required to exit
+ * @wait: Time-out in jiffies
  *
- * Polls the NCR5380 in a reasonably efficient manner waiting for
- * an event to occur, after a short quick poll we begin giving the
- * CPU back in non IRQ contexts
+ * 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 the value of the register or a negative error code.
+ * Returns 0 if event occurred otherwise -ETIMEDOUT.
  */
 
 static int NCR5380_poll_politely(struct Scsi_Host *instance,
-                                 int reg, int bit, int val, int t)
+                                 int reg, int bit, int val, int wait)
 {
-	int n = 500;
-	unsigned long end = jiffies + t;
-	int r;
-
-	while (n-- > 0) {
-		r = NCR5380_read(reg);
-		if ((r & bit) == val)
+	unsigned long start = jiffies;
+	unsigned long n;
+
+	/* Busy-wait for up to 1 jiffy */
+	n = loops_per_jiffy;
+	do {
+		if ((NCR5380_read(reg) & bit) == val)
 			return 0;
 		cpu_relax();
-	}
+	} while (--n > 0);
+
+	if (--wait <= 0)
+		return -ETIMEDOUT;
+
+	/* Busy-wait for up to 20 ms */
+	n = min(20000U, jiffies_to_usecs(wait));
+	do {
+		udelay(1);
+		if ((NCR5380_read(reg) & bit) == val)
+			return 0;
+		cpu_relax();
+	} while (--n > 0);
 
-	/* t time yet ? */
-	while (time_before(jiffies, end)) {
-		r = NCR5380_read(reg);
-		if ((r & bit) == val)
+	if (irqs_disabled() || in_interrupt())
+		return -ETIMEDOUT;
+
+	/* Repeatedly sleep for 1 ms until deadline */
+	while (time_is_after_jiffies(start + wait)) {
+		schedule_timeout_uninterruptible(1);
+		if ((NCR5380_read(reg) & bit) == val)
 			return 0;
-		if (!in_interrupt())
-			cond_resched();
-		else
-			cpu_relax();
 	}
+
 	return -ETIMEDOUT;
 }
 



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

* [PATCH 21/71] ncr5380: Sleep when polling, if possible
@ 2015-11-18  8:35   ` Finn Thain
  0 siblings, 0 replies; 268+ messages in thread
From: Finn Thain @ 2015-11-18  8:35 UTC (permalink / raw)
  To: James E.J. Bottomley, Michael Schmitz, linux-m68k, linux-scsi,
	linux-kernel

[-- Attachment #1: ncr5380-sleep-when-polling --]
[-- Type: text/plain, Size: 5533 bytes --]

When in process context, sleep during polling if doing so won't add
significant latency. In interrupt context or if the lock is held, poll
briefly then give up. Keep both core drivers in sync.

Signed-off-by: Finn Thain <fthain@telegraphics.com.au>

---
 drivers/scsi/NCR5380.c       |   73 +++++++++++++++++++++++++------------------
 drivers/scsi/atari_NCR5380.c |   58 +++++++++++++++++++++-------------
 2 files changed, 79 insertions(+), 52 deletions(-)

Index: linux/drivers/scsi/NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/NCR5380.c	2015-11-18 19:33:27.000000000 +1100
+++ linux/drivers/scsi/NCR5380.c	2015-11-18 19:33:31.000000000 +1100
@@ -293,44 +293,57 @@ static inline void initialize_SCp(struct
 }
 
 /**
- *	NCR5380_poll_politely	-	wait for NCR5380 status bits
- *	@instance: controller to poll
- *	@reg: 5380 register to poll
- *	@bit: Bitmask to check
- *	@val: Value required to exit
+ * NCR5380_poll_politely - wait for chip register value
+ * @instance: controller to poll
+ * @reg: 5380 register to poll
+ * @bit: Bitmask to check
+ * @val: Value required to exit
+ * @wait: Time-out in jiffies
  *
- *	Polls the NCR5380 in a reasonably efficient manner waiting for
- *	an event to occur, after a short quick poll we begin giving the
- *	CPU back in non IRQ contexts
+ * 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 the value of the register or a negative error code.
+ * Returns 0 if event occurred otherwise -ETIMEDOUT.
  */
- 
-static int NCR5380_poll_politely(struct Scsi_Host *instance, int reg, int bit, int val, int t)
+
+static int NCR5380_poll_politely(struct Scsi_Host *instance,
+                                 int reg, int bit, int val, int wait)
 {
-	int n = 500;		/* At about 8uS a cycle for the cpu access */
-	unsigned long end = jiffies + t;
-	int r;
-
-	while( n-- > 0)
-	{
-		r = NCR5380_read(reg);
-		if((r & bit) == val)
+	unsigned long start = jiffies;
+	unsigned long n;
+
+	/* Busy-wait for up to 1 jiffy */
+	n = loops_per_jiffy;
+	do {
+		if ((NCR5380_read(reg) & bit) == val)
 			return 0;
 		cpu_relax();
-	}
-	
-	/* t time yet ? */
-	while(time_before(jiffies, end))
-	{
-		r = NCR5380_read(reg);
-		if((r & bit) == val)
+	} while (--n > 0);
+
+	if (--wait <= 0)
+		return -ETIMEDOUT;
+
+	/* Busy-wait for up to 20 ms */
+	n = min(20000U, jiffies_to_usecs(wait));
+	do {
+		udelay(1);
+		if ((NCR5380_read(reg) & bit) == val)
+			return 0;
+		cpu_relax();
+	} while (--n > 0);
+
+	if (irqs_disabled() || in_interrupt())
+		return -ETIMEDOUT;
+
+	/* Repeatedly sleep for 1 ms until deadline */
+	while (time_is_after_jiffies(start + wait)) {
+		schedule_timeout_uninterruptible(1);
+		if ((NCR5380_read(reg) & bit) == val)
 			return 0;
-		if(!in_interrupt())
-			cond_resched();
-		else
-			cpu_relax();
 	}
+
 	return -ETIMEDOUT;
 }
 
Index: linux/drivers/scsi/atari_NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/atari_NCR5380.c	2015-11-18 19:33:27.000000000 +1100
+++ linux/drivers/scsi/atari_NCR5380.c	2015-11-18 19:33:31.000000000 +1100
@@ -479,43 +479,57 @@ static inline void initialize_SCp(struct
 }
 
 /**
- * NCR5380_poll_politely - wait for NCR5380 status bits
+ * NCR5380_poll_politely - wait for chip register value
  * @instance: controller to poll
  * @reg: 5380 register to poll
  * @bit: Bitmask to check
  * @val: Value required to exit
+ * @wait: Time-out in jiffies
  *
- * Polls the NCR5380 in a reasonably efficient manner waiting for
- * an event to occur, after a short quick poll we begin giving the
- * CPU back in non IRQ contexts
+ * 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 the value of the register or a negative error code.
+ * Returns 0 if event occurred otherwise -ETIMEDOUT.
  */
 
 static int NCR5380_poll_politely(struct Scsi_Host *instance,
-                                 int reg, int bit, int val, int t)
+                                 int reg, int bit, int val, int wait)
 {
-	int n = 500;
-	unsigned long end = jiffies + t;
-	int r;
-
-	while (n-- > 0) {
-		r = NCR5380_read(reg);
-		if ((r & bit) == val)
+	unsigned long start = jiffies;
+	unsigned long n;
+
+	/* Busy-wait for up to 1 jiffy */
+	n = loops_per_jiffy;
+	do {
+		if ((NCR5380_read(reg) & bit) == val)
 			return 0;
 		cpu_relax();
-	}
+	} while (--n > 0);
+
+	if (--wait <= 0)
+		return -ETIMEDOUT;
+
+	/* Busy-wait for up to 20 ms */
+	n = min(20000U, jiffies_to_usecs(wait));
+	do {
+		udelay(1);
+		if ((NCR5380_read(reg) & bit) == val)
+			return 0;
+		cpu_relax();
+	} while (--n > 0);
 
-	/* t time yet ? */
-	while (time_before(jiffies, end)) {
-		r = NCR5380_read(reg);
-		if ((r & bit) == val)
+	if (irqs_disabled() || in_interrupt())
+		return -ETIMEDOUT;
+
+	/* Repeatedly sleep for 1 ms until deadline */
+	while (time_is_after_jiffies(start + wait)) {
+		schedule_timeout_uninterruptible(1);
+		if ((NCR5380_read(reg) & bit) == val)
 			return 0;
-		if (!in_interrupt())
-			cond_resched();
-		else
-			cpu_relax();
 	}
+
 	return -ETIMEDOUT;
 }
 

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

* [PATCH 22/71] ncr5380: Eliminate selecting state
  2015-11-18  8:34 ` Finn Thain
@ 2015-11-18  8:35   ` Finn Thain
  -1 siblings, 0 replies; 268+ messages in thread
From: Finn Thain @ 2015-11-18  8:35 UTC (permalink / raw)
  To: James E.J. Bottomley, Michael Schmitz, linux-m68k, linux-scsi,
	linux-kernel

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: ncr5380-eliminate-selecting-state --]
[-- Type: text/plain, Size: 10107 bytes --]

Linux v2.1.105 changed the algorithm for polling for the BSY signal
in NCR5380_select() and NCR5380_main().

Presently, this code has a bug. Back then, NCR5380_set_timer(hostdata, 1)
meant reschedule main() after sleeping for 10 ms. Repeated 25 times this
provided the recommended 250 ms selection time-out delay. This got broken
when HZ became configurable.

We could fix this but there's no need to reschedule the main loop. This
BSY polling presently happens when the NCR5380_main() work queue item
calls NCR5380_select(), which in turn schedules NCR5380_main(), which
calls NCR5380_select() again, and so on.

This algorithm is a deviation from the simpler one in atari_NCR5380.c.
The extra complexity and state is pointless. There's no reason to
stop selection half-way and return to to the main loop when the main
loop can do nothing useful until selection completes.

So just poll for BSY. We can sleep while polling now that we have a
suitable workqueue.

Signed-off-by: Finn Thain <fthain@telegraphics.com.au>

---
 drivers/scsi/NCR5380.c       |   74 ++++++++-----------------------------------
 drivers/scsi/NCR5380.h       |    2 -
 drivers/scsi/atari_NCR5380.c |   49 ++++++++--------------------
 3 files changed, 29 insertions(+), 96 deletions(-)

Index: linux/drivers/scsi/NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/NCR5380.c	2015-11-18 19:33:31.000000000 +1100
+++ linux/drivers/scsi/NCR5380.c	2015-11-18 19:33:33.000000000 +1100
@@ -981,7 +981,7 @@ static void NCR5380_main(struct work_str
 	do {
 		/* Lock held here */
 		done = 1;
-		if (!hostdata->connected && !hostdata->selecting) {
+		if (!hostdata->connected) {
 			dprintk(NDEBUG_MAIN, "scsi%d : not connected\n", instance->host_no);
 			/*
 			 * Search through the issue_queue for a command destined
@@ -1011,9 +1011,6 @@ static void NCR5380_main(struct work_str
 					 */
 					dprintk(NDEBUG_MAIN|NDEBUG_QUEUES, "scsi%d : main() : command for target %d lun %llu removed from issue_queue\n", instance->host_no, tmp->device->id, tmp->device->lun);
 	
-					hostdata->selecting = NULL;
-					/* RvC: have to preset this to indicate a new command is being performed */
-
 					/*
 					 * REQUEST SENSE commands are issued without tagged
 					 * queueing, even on SCSI-II devices because the
@@ -1031,26 +1028,13 @@ static void NCR5380_main(struct work_str
 						done = 0;
 						dprintk(NDEBUG_MAIN|NDEBUG_QUEUES, "scsi%d : main(): select() failed, returned to issue_queue\n", instance->host_no);
 					}
-					if (hostdata->connected ||
-					    hostdata->selecting)
+					if (hostdata->connected)
 						break;
 					/* lock held here still */
 				}	/* if target/lun is not busy */
 			}	/* for */
 			/* exited locked */
 		}	/* if (!hostdata->connected) */
-		if (hostdata->selecting) {
-			tmp = (struct scsi_cmnd *) hostdata->selecting;
-			/* Selection will drop and retake the lock */
-			if (!NCR5380_select(instance, tmp)) {
-				/* OK or bad target */
-			} else {
-				LIST(tmp, hostdata->issue_queue);
-				tmp->host_scribble = (unsigned char *) hostdata->issue_queue;
-				hostdata->issue_queue = tmp;
-				done = 0;
-			}
-		}	/* if hostdata->selecting */
 		if (hostdata->connected
 #ifdef REAL_DMA
 		    && !hostdata->dmalen
@@ -1169,7 +1153,6 @@ static irqreturn_t NCR5380_intr(int dumm
  * Returns : -1 if selection failed but should be retried.
  *      0 if selection failed and should not be retried.
  *      0 if selection succeeded completely (hostdata->connected == cmd).
- *      0 if selection in progress (hostdata->selecting == cmd).
  *
  * Side effects : 
  *      If bus busy, arbitration failed, etc, NCR5380_select() will exit 
@@ -1193,13 +1176,8 @@ static int NCR5380_select(struct Scsi_Ho
 	unsigned char tmp[3], phase;
 	unsigned char *data;
 	int len;
-	unsigned long timeout;
-	unsigned char value;
 	int err;
 
-	if (hostdata->selecting)
-		goto part2;
-
 	NCR5380_dprint(NDEBUG_ARBITRATION, instance);
 	dprintk(NDEBUG_ARBITRATION, "scsi%d : starting arbitration, id = %d\n", instance->host_no, instance->this_id);
 
@@ -1335,33 +1313,9 @@ static int NCR5380_select(struct Scsi_Ho
 	 * selection.
 	 */
 
-	timeout = jiffies + msecs_to_jiffies(250);
-
-	/* 
-	 * XXX very interesting - we're seeing a bounce where the BSY we 
-	 * asserted is being reflected / still asserted (propagation delay?)
-	 * and it's detecting as true.  Sigh.
-	 */
-
-	hostdata->select_time = 0;	/* we count the clock ticks at which we polled */
-	hostdata->selecting = cmd;
-
-part2:
-	/* RvC: here we enter after a sleeping period, or immediately after
-	   execution of part 1
-	   we poll only once ech clock tick */
-	value = NCR5380_read(STATUS_REG) & (SR_BSY | SR_IO);
-
-	if (!value && (hostdata->select_time < HZ/4)) {
-		/* RvC: we still must wait for a device response */
-		hostdata->select_time++;	/* after 25 ticks the device has failed */
-		NCR5380_set_timer(hostdata, 1);
-		return 0;	/* RvC: we return here with hostdata->selecting set,
-				   to go to sleep */
-	}
+	err = NCR5380_poll_politely(instance, STATUS_REG, SR_BSY, SR_BSY,
+	                            msecs_to_jiffies(250));
 
-	hostdata->selecting = NULL;/* clear this pointer, because we passed the
-					   waiting period */
 	if ((NCR5380_read(STATUS_REG) & (SR_SEL | SR_IO)) == (SR_SEL | SR_IO)) {
 		NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
 		NCR5380_reselect(instance);
@@ -1369,6 +1323,17 @@ part2:
 		NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
 		return -1;
 	}
+
+	if (err < 0) {
+		NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
+		cmd->result = DID_BAD_TARGET << 16;
+		cmd->scsi_done(cmd);
+		NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
+		dprintk(NDEBUG_SELECTION, "scsi%d : target did not respond within 250ms\n",
+		        instance->host_no);
+		return 0;
+	}
+
 	/* 
 	 * No less than two deskew delays after the initiator detects the 
 	 * BSY signal is true, it shall release the SEL signal and may 
@@ -1379,15 +1344,6 @@ part2:
 
 	NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_ATN);
 
-	if (!(NCR5380_read(STATUS_REG) & SR_BSY)) {
-		NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
-		cmd->result = DID_BAD_TARGET << 16;
-		cmd->scsi_done(cmd);
-		NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
-		dprintk(NDEBUG_SELECTION, "scsi%d : target did not respond within 250ms\n", instance->host_no);
-		return 0;
-	}
-
 	/*
 	 * Since we followed the SCSI spec, and raised ATN while SEL 
 	 * was true but before BSY was false during selection, the information
Index: linux/drivers/scsi/NCR5380.h
===================================================================
--- linux.orig/drivers/scsi/NCR5380.h	2015-11-18 19:33:27.000000000 +1100
+++ linux/drivers/scsi/NCR5380.h	2015-11-18 19:33:33.000000000 +1100
@@ -267,8 +267,6 @@ struct NCR5380_hostdata {
 	volatile struct scsi_cmnd *disconnected_queue;	/* waiting for reconnect */
 	int flags;
 	unsigned long time_expires;		/* in jiffies, set prior to sleeping */
-	int select_time;			/* timer in select for target response */
-	volatile struct scsi_cmnd *selecting;
 	struct delayed_work coroutine;		/* our co-routine */
 	struct scsi_eh_save ses;
 	char info[256];
Index: linux/drivers/scsi/atari_NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/atari_NCR5380.c	2015-11-18 19:33:31.000000000 +1100
+++ linux/drivers/scsi/atari_NCR5380.c	2015-11-18 19:33:33.000000000 +1100
@@ -1425,7 +1425,7 @@ static int NCR5380_select(struct Scsi_Ho
 	unsigned char tmp[3], phase;
 	unsigned char *data;
 	int len;
-	unsigned long timeout;
+	int err;
 	unsigned long flags;
 
 	NCR5380_dprint(NDEBUG_ARBITRATION, instance);
@@ -1599,25 +1599,8 @@ static int NCR5380_select(struct Scsi_Ho
 	 * selection.
 	 */
 
-	timeout = jiffies + msecs_to_jiffies(250);
-
-	/*
-	 * XXX very interesting - we're seeing a bounce where the BSY we
-	 * asserted is being reflected / still asserted (propagation delay?)
-	 * and it's detecting as true.  Sigh.
-	 */
-
-#if 0
-	/* ++roman: If a target conformed to the SCSI standard, it wouldn't assert
-	 * IO while SEL is true. But again, there are some disks out the in the
-	 * world that do that nevertheless. (Somebody claimed that this announces
-	 * reselection capability of the target.) So we better skip that test and
-	 * only wait for BSY... (Famous german words: Der Klügere gibt nach :-)
-	 */
-
-	while (time_before(jiffies, timeout) &&
-	       !(NCR5380_read(STATUS_REG) & (SR_BSY | SR_IO)))
-		;
+	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)) {
 		NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
@@ -1627,22 +1610,8 @@ static int NCR5380_select(struct Scsi_Ho
 		NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
 		return -1;
 	}
-#else
-	while (time_before(jiffies, timeout) && !(NCR5380_read(STATUS_REG) & SR_BSY))
-		;
-#endif
-
-	/*
-	 * 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);
-
-	if (!(NCR5380_read(STATUS_REG) & SR_BSY)) {
+	if (err < 0) {
 		NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
 		cmd->result = DID_BAD_TARGET << 16;
 #ifdef SUPPORT_TAGS
@@ -1655,6 +1624,16 @@ static int NCR5380_select(struct Scsi_Ho
 	}
 
 	/*
+	 * 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



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

* [PATCH 22/71] ncr5380: Eliminate selecting state
@ 2015-11-18  8:35   ` Finn Thain
  0 siblings, 0 replies; 268+ messages in thread
From: Finn Thain @ 2015-11-18  8:35 UTC (permalink / raw)
  To: James E.J. Bottomley, Michael Schmitz, linux-m68k, linux-scsi,
	linux-kernel

[-- Attachment #1: ncr5380-eliminate-selecting-state --]
[-- Type: TEXT/PLAIN, Size: 10372 bytes --]

Linux v2.1.105 changed the algorithm for polling for the BSY signal
in NCR5380_select() and NCR5380_main().

Presently, this code has a bug. Back then, NCR5380_set_timer(hostdata, 1)
meant reschedule main() after sleeping for 10 ms. Repeated 25 times this
provided the recommended 250 ms selection time-out delay. This got broken
when HZ became configurable.

We could fix this but there's no need to reschedule the main loop. This
BSY polling presently happens when the NCR5380_main() work queue item
calls NCR5380_select(), which in turn schedules NCR5380_main(), which
calls NCR5380_select() again, and so on.

This algorithm is a deviation from the simpler one in atari_NCR5380.c.
The extra complexity and state is pointless. There's no reason to
stop selection half-way and return to to the main loop when the main
loop can do nothing useful until selection completes.

So just poll for BSY. We can sleep while polling now that we have a
suitable workqueue.

Signed-off-by: Finn Thain <fthain@telegraphics.com.au>

---
 drivers/scsi/NCR5380.c       |   74 ++++++++-----------------------------------
 drivers/scsi/NCR5380.h       |    2 -
 drivers/scsi/atari_NCR5380.c |   49 ++++++++--------------------
 3 files changed, 29 insertions(+), 96 deletions(-)

Index: linux/drivers/scsi/NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/NCR5380.c	2015-11-18 19:33:31.000000000 +1100
+++ linux/drivers/scsi/NCR5380.c	2015-11-18 19:33:33.000000000 +1100
@@ -981,7 +981,7 @@ static void NCR5380_main(struct work_str
 	do {
 		/* Lock held here */
 		done = 1;
-		if (!hostdata->connected && !hostdata->selecting) {
+		if (!hostdata->connected) {
 			dprintk(NDEBUG_MAIN, "scsi%d : not connected\n", instance->host_no);
 			/*
 			 * Search through the issue_queue for a command destined
@@ -1011,9 +1011,6 @@ static void NCR5380_main(struct work_str
 					 */
 					dprintk(NDEBUG_MAIN|NDEBUG_QUEUES, "scsi%d : main() : command for target %d lun %llu removed from issue_queue\n", instance->host_no, tmp->device->id, tmp->device->lun);
 	
-					hostdata->selecting = NULL;
-					/* RvC: have to preset this to indicate a new command is being performed */
-
 					/*
 					 * REQUEST SENSE commands are issued without tagged
 					 * queueing, even on SCSI-II devices because the
@@ -1031,26 +1028,13 @@ static void NCR5380_main(struct work_str
 						done = 0;
 						dprintk(NDEBUG_MAIN|NDEBUG_QUEUES, "scsi%d : main(): select() failed, returned to issue_queue\n", instance->host_no);
 					}
-					if (hostdata->connected ||
-					    hostdata->selecting)
+					if (hostdata->connected)
 						break;
 					/* lock held here still */
 				}	/* if target/lun is not busy */
 			}	/* for */
 			/* exited locked */
 		}	/* if (!hostdata->connected) */
-		if (hostdata->selecting) {
-			tmp = (struct scsi_cmnd *) hostdata->selecting;
-			/* Selection will drop and retake the lock */
-			if (!NCR5380_select(instance, tmp)) {
-				/* OK or bad target */
-			} else {
-				LIST(tmp, hostdata->issue_queue);
-				tmp->host_scribble = (unsigned char *) hostdata->issue_queue;
-				hostdata->issue_queue = tmp;
-				done = 0;
-			}
-		}	/* if hostdata->selecting */
 		if (hostdata->connected
 #ifdef REAL_DMA
 		    && !hostdata->dmalen
@@ -1169,7 +1153,6 @@ static irqreturn_t NCR5380_intr(int dumm
  * Returns : -1 if selection failed but should be retried.
  *      0 if selection failed and should not be retried.
  *      0 if selection succeeded completely (hostdata->connected == cmd).
- *      0 if selection in progress (hostdata->selecting == cmd).
  *
  * Side effects : 
  *      If bus busy, arbitration failed, etc, NCR5380_select() will exit 
@@ -1193,13 +1176,8 @@ static int NCR5380_select(struct Scsi_Ho
 	unsigned char tmp[3], phase;
 	unsigned char *data;
 	int len;
-	unsigned long timeout;
-	unsigned char value;
 	int err;
 
-	if (hostdata->selecting)
-		goto part2;
-
 	NCR5380_dprint(NDEBUG_ARBITRATION, instance);
 	dprintk(NDEBUG_ARBITRATION, "scsi%d : starting arbitration, id = %d\n", instance->host_no, instance->this_id);
 
@@ -1335,33 +1313,9 @@ static int NCR5380_select(struct Scsi_Ho
 	 * selection.
 	 */
 
-	timeout = jiffies + msecs_to_jiffies(250);
-
-	/* 
-	 * XXX very interesting - we're seeing a bounce where the BSY we 
-	 * asserted is being reflected / still asserted (propagation delay?)
-	 * and it's detecting as true.  Sigh.
-	 */
-
-	hostdata->select_time = 0;	/* we count the clock ticks at which we polled */
-	hostdata->selecting = cmd;
-
-part2:
-	/* RvC: here we enter after a sleeping period, or immediately after
-	   execution of part 1
-	   we poll only once ech clock tick */
-	value = NCR5380_read(STATUS_REG) & (SR_BSY | SR_IO);
-
-	if (!value && (hostdata->select_time < HZ/4)) {
-		/* RvC: we still must wait for a device response */
-		hostdata->select_time++;	/* after 25 ticks the device has failed */
-		NCR5380_set_timer(hostdata, 1);
-		return 0;	/* RvC: we return here with hostdata->selecting set,
-				   to go to sleep */
-	}
+	err = NCR5380_poll_politely(instance, STATUS_REG, SR_BSY, SR_BSY,
+	                            msecs_to_jiffies(250));
 
-	hostdata->selecting = NULL;/* clear this pointer, because we passed the
-					   waiting period */
 	if ((NCR5380_read(STATUS_REG) & (SR_SEL | SR_IO)) == (SR_SEL | SR_IO)) {
 		NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
 		NCR5380_reselect(instance);
@@ -1369,6 +1323,17 @@ part2:
 		NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
 		return -1;
 	}
+
+	if (err < 0) {
+		NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
+		cmd->result = DID_BAD_TARGET << 16;
+		cmd->scsi_done(cmd);
+		NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
+		dprintk(NDEBUG_SELECTION, "scsi%d : target did not respond within 250ms\n",
+		        instance->host_no);
+		return 0;
+	}
+
 	/* 
 	 * No less than two deskew delays after the initiator detects the 
 	 * BSY signal is true, it shall release the SEL signal and may 
@@ -1379,15 +1344,6 @@ part2:
 
 	NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_ATN);
 
-	if (!(NCR5380_read(STATUS_REG) & SR_BSY)) {
-		NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
-		cmd->result = DID_BAD_TARGET << 16;
-		cmd->scsi_done(cmd);
-		NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
-		dprintk(NDEBUG_SELECTION, "scsi%d : target did not respond within 250ms\n", instance->host_no);
-		return 0;
-	}
-
 	/*
 	 * Since we followed the SCSI spec, and raised ATN while SEL 
 	 * was true but before BSY was false during selection, the information
Index: linux/drivers/scsi/NCR5380.h
===================================================================
--- linux.orig/drivers/scsi/NCR5380.h	2015-11-18 19:33:27.000000000 +1100
+++ linux/drivers/scsi/NCR5380.h	2015-11-18 19:33:33.000000000 +1100
@@ -267,8 +267,6 @@ struct NCR5380_hostdata {
 	volatile struct scsi_cmnd *disconnected_queue;	/* waiting for reconnect */
 	int flags;
 	unsigned long time_expires;		/* in jiffies, set prior to sleeping */
-	int select_time;			/* timer in select for target response */
-	volatile struct scsi_cmnd *selecting;
 	struct delayed_work coroutine;		/* our co-routine */
 	struct scsi_eh_save ses;
 	char info[256];
Index: linux/drivers/scsi/atari_NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/atari_NCR5380.c	2015-11-18 19:33:31.000000000 +1100
+++ linux/drivers/scsi/atari_NCR5380.c	2015-11-18 19:33:33.000000000 +1100
@@ -1425,7 +1425,7 @@ static int NCR5380_select(struct Scsi_Ho
 	unsigned char tmp[3], phase;
 	unsigned char *data;
 	int len;
-	unsigned long timeout;
+	int err;
 	unsigned long flags;
 
 	NCR5380_dprint(NDEBUG_ARBITRATION, instance);
@@ -1599,25 +1599,8 @@ static int NCR5380_select(struct Scsi_Ho
 	 * selection.
 	 */
 
-	timeout = jiffies + msecs_to_jiffies(250);
-
-	/*
-	 * XXX very interesting - we're seeing a bounce where the BSY we
-	 * asserted is being reflected / still asserted (propagation delay?)
-	 * and it's detecting as true.  Sigh.
-	 */
-
-#if 0
-	/* ++roman: If a target conformed to the SCSI standard, it wouldn't assert
-	 * IO while SEL is true. But again, there are some disks out the in the
-	 * world that do that nevertheless. (Somebody claimed that this announces
-	 * reselection capability of the target.) So we better skip that test and
-	 * only wait for BSY... (Famous german words: Der Klügere gibt nach :-)
-	 */
-
-	while (time_before(jiffies, timeout) &&
-	       !(NCR5380_read(STATUS_REG) & (SR_BSY | SR_IO)))
-		;
+	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)) {
 		NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
@@ -1627,22 +1610,8 @@ static int NCR5380_select(struct Scsi_Ho
 		NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
 		return -1;
 	}
-#else
-	while (time_before(jiffies, timeout) && !(NCR5380_read(STATUS_REG) & SR_BSY))
-		;
-#endif
-
-	/*
-	 * 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);
-
-	if (!(NCR5380_read(STATUS_REG) & SR_BSY)) {
+	if (err < 0) {
 		NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
 		cmd->result = DID_BAD_TARGET << 16;
 #ifdef SUPPORT_TAGS
@@ -1655,6 +1624,16 @@ static int NCR5380_select(struct Scsi_Ho
 	}
 
 	/*
+	 * 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

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

* [PATCH 23/71] ncr5380: Always retry arbitration and selection
  2015-11-18  8:34 ` Finn Thain
@ 2015-11-18  8:35   ` Finn Thain
  -1 siblings, 0 replies; 268+ messages in thread
From: Finn Thain @ 2015-11-18  8:35 UTC (permalink / raw)
  To: James E.J. Bottomley, Michael Schmitz, linux-m68k, linux-scsi,
	linux-kernel

[-- Attachment #1: ncr5380-retry-selection-phase --]
[-- Type: text/plain, Size: 1819 bytes --]

If NCR5380_select() returns -1, it means arbitration was lost or selection
failed and should be retried. If the main loop simply terminates when there
are still commands on the issue queue, they will remain queued until they
expire.

Fix this by clearing the 'done' flag after selection failure or lost
arbitration.

The "else break" clause in NCR5380_main() that gets removed here appears
to be a vestige of a long-gone loop that iterated over host instances.
See commit 491447e1fcff ("[PATCH] next NCR5380 updates") in
history/history.git.

Signed-off-by: Finn Thain <fthain@telegraphics.com.au>

---
 drivers/scsi/NCR5380.c       |    3 +--
 drivers/scsi/atari_NCR5380.c |    1 +
 2 files changed, 2 insertions(+), 2 deletions(-)

Index: linux/drivers/scsi/NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/NCR5380.c	2015-11-18 19:33:33.000000000 +1100
+++ linux/drivers/scsi/NCR5380.c	2015-11-18 19:33:34.000000000 +1100
@@ -1045,8 +1045,7 @@ static void NCR5380_main(struct work_str
 			NCR5380_information_transfer(instance);
 			dprintk(NDEBUG_MAIN, "scsi%d : main() : done set false\n", instance->host_no);
 			done = 0;
-		} else
-			break;
+		}
 	} while (!done);
 	
 	spin_unlock_irq(instance->host_lock);
Index: linux/drivers/scsi/atari_NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/atari_NCR5380.c	2015-11-18 19:33:33.000000000 +1100
+++ linux/drivers/scsi/atari_NCR5380.c	2015-11-18 19:33:34.000000000 +1100
@@ -1175,6 +1175,7 @@ static void NCR5380_main(struct work_str
 #endif
 						hostdata->retain_dma_intr--;
 						local_irq_restore(flags);
+						done = 0;
 						dprintk(NDEBUG_MAIN, "scsi%d: main(): select() failed, "
 							    "returned to issue_queue\n", HOSTNO);
 					}



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

* [PATCH 23/71] ncr5380: Always retry arbitration and selection
@ 2015-11-18  8:35   ` Finn Thain
  0 siblings, 0 replies; 268+ messages in thread
From: Finn Thain @ 2015-11-18  8:35 UTC (permalink / raw)
  To: James E.J. Bottomley, Michael Schmitz, linux-m68k, linux-scsi,
	linux-kernel

[-- Attachment #1: ncr5380-retry-selection-phase --]
[-- Type: text/plain, Size: 1817 bytes --]

If NCR5380_select() returns -1, it means arbitration was lost or selection
failed and should be retried. If the main loop simply terminates when there
are still commands on the issue queue, they will remain queued until they
expire.

Fix this by clearing the 'done' flag after selection failure or lost
arbitration.

The "else break" clause in NCR5380_main() that gets removed here appears
to be a vestige of a long-gone loop that iterated over host instances.
See commit 491447e1fcff ("[PATCH] next NCR5380 updates") in
history/history.git.

Signed-off-by: Finn Thain <fthain@telegraphics.com.au>

---
 drivers/scsi/NCR5380.c       |    3 +--
 drivers/scsi/atari_NCR5380.c |    1 +
 2 files changed, 2 insertions(+), 2 deletions(-)

Index: linux/drivers/scsi/NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/NCR5380.c	2015-11-18 19:33:33.000000000 +1100
+++ linux/drivers/scsi/NCR5380.c	2015-11-18 19:33:34.000000000 +1100
@@ -1045,8 +1045,7 @@ static void NCR5380_main(struct work_str
 			NCR5380_information_transfer(instance);
 			dprintk(NDEBUG_MAIN, "scsi%d : main() : done set false\n", instance->host_no);
 			done = 0;
-		} else
-			break;
+		}
 	} while (!done);
 	
 	spin_unlock_irq(instance->host_lock);
Index: linux/drivers/scsi/atari_NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/atari_NCR5380.c	2015-11-18 19:33:33.000000000 +1100
+++ linux/drivers/scsi/atari_NCR5380.c	2015-11-18 19:33:34.000000000 +1100
@@ -1175,6 +1175,7 @@ static void NCR5380_main(struct work_str
 #endif
 						hostdata->retain_dma_intr--;
 						local_irq_restore(flags);
+						done = 0;
 						dprintk(NDEBUG_MAIN, "scsi%d: main(): select() failed, "
 							    "returned to issue_queue\n", HOSTNO);
 					}

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

* [PATCH 24/71] ncr5380: Implement NCR5380_dma_xfer_len and remove LIMIT_TRANSFERSIZE macro
  2015-11-18  8:34 ` Finn Thain
  (?)
@ 2015-11-18  8:35   ` Finn Thain
  -1 siblings, 0 replies; 268+ messages in thread
From: Finn Thain @ 2015-11-18  8:35 UTC (permalink / raw)
  To: James E.J. Bottomley, Michael Schmitz, linux-m68k, linux-scsi,
	linux-kernel, Russell King, linux-arm-kernel

[-- Attachment #1: ncr5380-implement-NCR5380_dma_xfer_len --]
[-- Type: text/plain, Size: 9613 bytes --]

Follow the example of the atari_NCR5380.c core driver and adopt the
NCR5380_dma_xfer_len() hook. Implement NCR5380_dma_xfer_len() for dtc.c
and g_NCR5380.c to take care of the limitations of these cards. Keep the
default for drivers using PSEUDO_DMA.

Eliminate the unused macro LIMIT_TRANSFERSIZE. 

Signed-off-by: Finn Thain <fthain@telegraphics.com.au>

---
 drivers/scsi/NCR5380.c       |   32 +++++---------------------------
 drivers/scsi/arm/cumana_1.c  |    3 +++
 drivers/scsi/arm/oak.c       |    2 ++
 drivers/scsi/atari_NCR5380.c |    8 +++++---
 drivers/scsi/dtc.c           |   14 ++++++++++++++
 drivers/scsi/dtc.h           |    3 +++
 drivers/scsi/g_NCR5380.c     |   15 +++++++++++++++
 drivers/scsi/g_NCR5380.h     |    3 +++
 drivers/scsi/mac_scsi.c      |    1 +
 drivers/scsi/pas16.h         |    2 ++
 drivers/scsi/t128.h          |    2 ++
 11 files changed, 55 insertions(+), 30 deletions(-)

Index: linux/drivers/scsi/NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/NCR5380.c	2015-11-18 19:33:34.000000000 +1100
+++ linux/drivers/scsi/NCR5380.c	2015-11-18 19:33:35.000000000 +1100
@@ -201,11 +201,6 @@
  * DONT_USE_INTR - if defined, never use interrupts, even if we probe or
  *      override-configure an IRQ.
  *
- * LIMIT_TRANSFERSIZE - if defined, limit the pseudo-dma transfers to 512
- *      bytes at a time.  Since interrupts are disabled by default during
- *      these transfers, we might need this to give reasonable interrupt
- *      service time if the transfer size gets too large.
- *
  * LINKED - if defined, linked commands are supported.
  *
  * PSEUDO_DMA - if defined, PSEUDO DMA is used during the data transfer phases.
@@ -1993,29 +1988,12 @@ static void NCR5380_information_transfer
 				 */
 
 #if defined(PSEUDO_DMA) || defined(REAL_DMA_POLL)
-				/* KLL
-				 * PSEUDO_DMA is defined here. If this is the g_NCR5380
-				 * driver then it will always be defined, so the
-				 * FLAG_NO_PSEUDO_DMA is used to inhibit PDMA in the base
-				 * NCR5380 case.  I think this is a fairly clean solution.
-				 * We supplement these 2 if's with the flag.
-				 */
-#ifdef NCR5380_dma_xfer_len
-				if (!cmd->device->borken && !(hostdata->flags & FLAG_NO_PSEUDO_DMA) && (transfersize = NCR5380_dma_xfer_len(instance, cmd)) != 0) {
-#else
-				transfersize = cmd->transfersize;
+				transfersize = 0;
+				if (!cmd->device->borken &&
+				    !(hostdata->flags & FLAG_NO_PSEUDO_DMA))
+					transfersize = NCR5380_dma_xfer_len(instance, cmd, phase);
 
-#ifdef LIMIT_TRANSFERSIZE	/* If we have problems with interrupt service */
-				if (transfersize > 512)
-					transfersize = 512;
-#endif				/* LIMIT_TRANSFERSIZE */
-
-				if (!cmd->device->borken && transfersize && !(hostdata->flags & FLAG_NO_PSEUDO_DMA) && cmd->SCp.this_residual && !(cmd->SCp.this_residual % transfersize)) {
-					/* Limit transfers to 32K, for xx400 & xx406
-					 * pseudoDMA that transfers in 128 bytes blocks. */
-					if (transfersize > 32 * 1024)
-						transfersize = 32 * 1024;
-#endif
+				if (transfersize) {
 					len = transfersize;
 					if (NCR5380_transfer_dma(instance, &phase, &len, (unsigned char **) &cmd->SCp.ptr)) {
 						/*
Index: linux/drivers/scsi/atari_NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/atari_NCR5380.c	2015-11-18 19:33:34.000000000 +1100
+++ linux/drivers/scsi/atari_NCR5380.c	2015-11-18 19:33:35.000000000 +1100
@@ -2164,11 +2164,13 @@ static void NCR5380_information_transfer
 				 */
 
 #if defined(REAL_DMA)
-				if (
 #if !defined(CONFIG_SUN3)
-				    !cmd->device->borken &&
+				transfersize = 0;
+				if (!cmd->device->borken)
 #endif
-				    (transfersize = NCR5380_dma_xfer_len(instance, cmd, phase)) >= DMA_MIN_SIZE) {
+					transfersize = NCR5380_dma_xfer_len(instance, cmd, phase);
+
+				if (transfersize >= DMA_MIN_SIZE) {
 					len = transfersize;
 					cmd->SCp.phase = phase;
 					if (NCR5380_transfer_dma(instance, &phase,
Index: linux/drivers/scsi/dtc.c
===================================================================
--- linux.orig/drivers/scsi/dtc.c	2015-11-18 19:33:27.000000000 +1100
+++ linux/drivers/scsi/dtc.c	2015-11-18 19:33:35.000000000 +1100
@@ -419,6 +419,20 @@ static inline int NCR5380_pwrite(struct
 	return (0);
 }
 
+static int dtc_dma_xfer_len(struct scsi_cmnd *cmd)
+{
+	int transfersize = cmd->transfersize;
+
+	/* Limit transfers to 32K, for xx400 & xx406
+	 * pseudoDMA that transfers in 128 bytes blocks.
+	 */
+	if (transfersize > 32 * 1024 && cmd->SCp.this_residual &&
+	    !(cmd->SCp.this_residual % transfersize))
+		transfersize = 32 * 1024;
+
+	return transfersize;
+}
+
 MODULE_LICENSE("GPL");
 
 #include "NCR5380.c"
Index: linux/drivers/scsi/g_NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/g_NCR5380.c	2015-11-18 19:33:27.000000000 +1100
+++ linux/drivers/scsi/g_NCR5380.c	2015-11-18 19:33:35.000000000 +1100
@@ -701,6 +701,21 @@ static inline int NCR5380_pwrite(struct
 		; 	// TIMEOUT
 	return 0;
 }
+
+static int generic_NCR5380_dma_xfer_len(struct scsi_cmnd *cmd)
+{
+	int transfersize = cmd->transfersize;
+
+	/* Limit transfers to 32K, for xx400 & xx406
+	 * pseudoDMA that transfers in 128 bytes blocks.
+	 */
+	if (transfersize > 32 * 1024 && cmd->SCp.this_residual &&
+	    !(cmd->SCp.this_residual % transfersize))
+		transfersize = 32 * 1024;
+
+	return transfersize;
+}
+
 #endif /* PSEUDO_DMA */
 
 /*
Index: linux/drivers/scsi/g_NCR5380.h
===================================================================
--- linux.orig/drivers/scsi/g_NCR5380.h	2015-11-18 19:33:12.000000000 +1100
+++ linux/drivers/scsi/g_NCR5380.h	2015-11-18 19:33:35.000000000 +1100
@@ -73,6 +73,9 @@
 
 #endif
 
+#define NCR5380_dma_xfer_len(instance, cmd, phase) \
+        generic_NCR5380_dma_xfer_len(cmd)
+
 #define NCR5380_intr generic_NCR5380_intr
 #define NCR5380_queue_command generic_NCR5380_queue_command
 #define NCR5380_abort generic_NCR5380_abort
Index: linux/drivers/scsi/dtc.h
===================================================================
--- linux.orig/drivers/scsi/dtc.h	2015-11-18 19:33:05.000000000 +1100
+++ linux/drivers/scsi/dtc.h	2015-11-18 19:33:35.000000000 +1100
@@ -27,6 +27,9 @@
 #define NCR5380_read(reg) (readb(DTC_address(reg)))
 #define NCR5380_write(reg, value) (writeb(value, DTC_address(reg)))
 
+#define NCR5380_dma_xfer_len(instance, cmd, phase) \
+        dtc_dma_xfer_len(cmd)
+
 #define NCR5380_intr			dtc_intr
 #define NCR5380_queue_command		dtc_queue_command
 #define NCR5380_abort			dtc_abort
Index: linux/drivers/scsi/arm/cumana_1.c
===================================================================
--- linux.orig/drivers/scsi/arm/cumana_1.c	2015-11-18 19:33:27.000000000 +1100
+++ linux/drivers/scsi/arm/cumana_1.c	2015-11-18 19:33:35.000000000 +1100
@@ -22,6 +22,9 @@
 #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)
+
+#define NCR5380_dma_xfer_len(instance, cmd, phase)	(cmd->transfersize)
+
 #define NCR5380_intr			cumanascsi_intr
 #define NCR5380_queue_command		cumanascsi_queue_command
 #define NCR5380_info			cumanascsi_info
Index: linux/drivers/scsi/arm/oak.c
===================================================================
--- linux.orig/drivers/scsi/arm/oak.c	2015-11-18 19:33:27.000000000 +1100
+++ linux/drivers/scsi/arm/oak.c	2015-11-18 19:33:35.000000000 +1100
@@ -26,6 +26,8 @@
 #define NCR5380_write(reg, value) \
 	writeb(value, priv(instance)->base + ((reg) << 2))
 
+#define NCR5380_dma_xfer_len(instance, cmd, phase)	(cmd->transfersize)
+
 #define NCR5380_queue_command		oakscsi_queue_command
 #define NCR5380_info			oakscsi_info
 #define NCR5380_show_info		oakscsi_show_info
Index: linux/drivers/scsi/mac_scsi.c
===================================================================
--- linux.orig/drivers/scsi/mac_scsi.c	2015-11-18 19:33:27.000000000 +1100
+++ linux/drivers/scsi/mac_scsi.c	2015-11-18 19:33:35.000000000 +1100
@@ -38,6 +38,7 @@
 
 #define NCR5380_pread                   macscsi_pread
 #define NCR5380_pwrite                  macscsi_pwrite
+#define NCR5380_dma_xfer_len(instance, cmd, phase)	(cmd->transfersize)
 
 #define NCR5380_intr                    macscsi_intr
 #define NCR5380_queue_command           macscsi_queue_command
Index: linux/drivers/scsi/pas16.h
===================================================================
--- linux.orig/drivers/scsi/pas16.h	2015-11-18 19:33:05.000000000 +1100
+++ linux/drivers/scsi/pas16.h	2015-11-18 19:33:35.000000000 +1100
@@ -110,6 +110,8 @@
 #define NCR5380_read(reg) ( inb(PAS16_io_port(reg)) )
 #define NCR5380_write(reg, value) ( outb((value),PAS16_io_port(reg)) )
 
+#define NCR5380_dma_xfer_len(instance, cmd, phase)	(cmd->transfersize)
+
 #define NCR5380_intr pas16_intr
 #define NCR5380_queue_command pas16_queue_command
 #define NCR5380_abort pas16_abort
Index: linux/drivers/scsi/t128.h
===================================================================
--- linux.orig/drivers/scsi/t128.h	2015-11-18 19:33:05.000000000 +1100
+++ linux/drivers/scsi/t128.h	2015-11-18 19:33:35.000000000 +1100
@@ -84,6 +84,8 @@
 #define NCR5380_read(reg) readb(T128_address(reg))
 #define NCR5380_write(reg, value) writeb((value),(T128_address(reg)))
 
+#define NCR5380_dma_xfer_len(instance, cmd, phase)	(cmd->transfersize)
+
 #define NCR5380_intr t128_intr
 #define NCR5380_queue_command t128_queue_command
 #define NCR5380_abort t128_abort



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

* [PATCH 24/71] ncr5380: Implement NCR5380_dma_xfer_len and remove LIMIT_TRANSFERSIZE macro
@ 2015-11-18  8:35   ` Finn Thain
  0 siblings, 0 replies; 268+ messages in thread
From: Finn Thain @ 2015-11-18  8:35 UTC (permalink / raw)
  To: James E.J. Bottomley, Michael Schmitz, linux-m68k, linux-scsi,
	linux-kernel, Russell King, linux-arm-kernel

[-- Attachment #1: ncr5380-implement-NCR5380_dma_xfer_len --]
[-- Type: text/plain, Size: 9611 bytes --]

Follow the example of the atari_NCR5380.c core driver and adopt the
NCR5380_dma_xfer_len() hook. Implement NCR5380_dma_xfer_len() for dtc.c
and g_NCR5380.c to take care of the limitations of these cards. Keep the
default for drivers using PSEUDO_DMA.

Eliminate the unused macro LIMIT_TRANSFERSIZE. 

Signed-off-by: Finn Thain <fthain@telegraphics.com.au>

---
 drivers/scsi/NCR5380.c       |   32 +++++---------------------------
 drivers/scsi/arm/cumana_1.c  |    3 +++
 drivers/scsi/arm/oak.c       |    2 ++
 drivers/scsi/atari_NCR5380.c |    8 +++++---
 drivers/scsi/dtc.c           |   14 ++++++++++++++
 drivers/scsi/dtc.h           |    3 +++
 drivers/scsi/g_NCR5380.c     |   15 +++++++++++++++
 drivers/scsi/g_NCR5380.h     |    3 +++
 drivers/scsi/mac_scsi.c      |    1 +
 drivers/scsi/pas16.h         |    2 ++
 drivers/scsi/t128.h          |    2 ++
 11 files changed, 55 insertions(+), 30 deletions(-)

Index: linux/drivers/scsi/NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/NCR5380.c	2015-11-18 19:33:34.000000000 +1100
+++ linux/drivers/scsi/NCR5380.c	2015-11-18 19:33:35.000000000 +1100
@@ -201,11 +201,6 @@
  * DONT_USE_INTR - if defined, never use interrupts, even if we probe or
  *      override-configure an IRQ.
  *
- * LIMIT_TRANSFERSIZE - if defined, limit the pseudo-dma transfers to 512
- *      bytes at a time.  Since interrupts are disabled by default during
- *      these transfers, we might need this to give reasonable interrupt
- *      service time if the transfer size gets too large.
- *
  * LINKED - if defined, linked commands are supported.
  *
  * PSEUDO_DMA - if defined, PSEUDO DMA is used during the data transfer phases.
@@ -1993,29 +1988,12 @@ static void NCR5380_information_transfer
 				 */
 
 #if defined(PSEUDO_DMA) || defined(REAL_DMA_POLL)
-				/* KLL
-				 * PSEUDO_DMA is defined here. If this is the g_NCR5380
-				 * driver then it will always be defined, so the
-				 * FLAG_NO_PSEUDO_DMA is used to inhibit PDMA in the base
-				 * NCR5380 case.  I think this is a fairly clean solution.
-				 * We supplement these 2 if's with the flag.
-				 */
-#ifdef NCR5380_dma_xfer_len
-				if (!cmd->device->borken && !(hostdata->flags & FLAG_NO_PSEUDO_DMA) && (transfersize = NCR5380_dma_xfer_len(instance, cmd)) != 0) {
-#else
-				transfersize = cmd->transfersize;
+				transfersize = 0;
+				if (!cmd->device->borken &&
+				    !(hostdata->flags & FLAG_NO_PSEUDO_DMA))
+					transfersize = NCR5380_dma_xfer_len(instance, cmd, phase);
 
-#ifdef LIMIT_TRANSFERSIZE	/* If we have problems with interrupt service */
-				if (transfersize > 512)
-					transfersize = 512;
-#endif				/* LIMIT_TRANSFERSIZE */
-
-				if (!cmd->device->borken && transfersize && !(hostdata->flags & FLAG_NO_PSEUDO_DMA) && cmd->SCp.this_residual && !(cmd->SCp.this_residual % transfersize)) {
-					/* Limit transfers to 32K, for xx400 & xx406
-					 * pseudoDMA that transfers in 128 bytes blocks. */
-					if (transfersize > 32 * 1024)
-						transfersize = 32 * 1024;
-#endif
+				if (transfersize) {
 					len = transfersize;
 					if (NCR5380_transfer_dma(instance, &phase, &len, (unsigned char **) &cmd->SCp.ptr)) {
 						/*
Index: linux/drivers/scsi/atari_NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/atari_NCR5380.c	2015-11-18 19:33:34.000000000 +1100
+++ linux/drivers/scsi/atari_NCR5380.c	2015-11-18 19:33:35.000000000 +1100
@@ -2164,11 +2164,13 @@ static void NCR5380_information_transfer
 				 */
 
 #if defined(REAL_DMA)
-				if (
 #if !defined(CONFIG_SUN3)
-				    !cmd->device->borken &&
+				transfersize = 0;
+				if (!cmd->device->borken)
 #endif
-				    (transfersize = NCR5380_dma_xfer_len(instance, cmd, phase)) >= DMA_MIN_SIZE) {
+					transfersize = NCR5380_dma_xfer_len(instance, cmd, phase);
+
+				if (transfersize >= DMA_MIN_SIZE) {
 					len = transfersize;
 					cmd->SCp.phase = phase;
 					if (NCR5380_transfer_dma(instance, &phase,
Index: linux/drivers/scsi/dtc.c
===================================================================
--- linux.orig/drivers/scsi/dtc.c	2015-11-18 19:33:27.000000000 +1100
+++ linux/drivers/scsi/dtc.c	2015-11-18 19:33:35.000000000 +1100
@@ -419,6 +419,20 @@ static inline int NCR5380_pwrite(struct
 	return (0);
 }
 
+static int dtc_dma_xfer_len(struct scsi_cmnd *cmd)
+{
+	int transfersize = cmd->transfersize;
+
+	/* Limit transfers to 32K, for xx400 & xx406
+	 * pseudoDMA that transfers in 128 bytes blocks.
+	 */
+	if (transfersize > 32 * 1024 && cmd->SCp.this_residual &&
+	    !(cmd->SCp.this_residual % transfersize))
+		transfersize = 32 * 1024;
+
+	return transfersize;
+}
+
 MODULE_LICENSE("GPL");
 
 #include "NCR5380.c"
Index: linux/drivers/scsi/g_NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/g_NCR5380.c	2015-11-18 19:33:27.000000000 +1100
+++ linux/drivers/scsi/g_NCR5380.c	2015-11-18 19:33:35.000000000 +1100
@@ -701,6 +701,21 @@ static inline int NCR5380_pwrite(struct
 		; 	// TIMEOUT
 	return 0;
 }
+
+static int generic_NCR5380_dma_xfer_len(struct scsi_cmnd *cmd)
+{
+	int transfersize = cmd->transfersize;
+
+	/* Limit transfers to 32K, for xx400 & xx406
+	 * pseudoDMA that transfers in 128 bytes blocks.
+	 */
+	if (transfersize > 32 * 1024 && cmd->SCp.this_residual &&
+	    !(cmd->SCp.this_residual % transfersize))
+		transfersize = 32 * 1024;
+
+	return transfersize;
+}
+
 #endif /* PSEUDO_DMA */
 
 /*
Index: linux/drivers/scsi/g_NCR5380.h
===================================================================
--- linux.orig/drivers/scsi/g_NCR5380.h	2015-11-18 19:33:12.000000000 +1100
+++ linux/drivers/scsi/g_NCR5380.h	2015-11-18 19:33:35.000000000 +1100
@@ -73,6 +73,9 @@
 
 #endif
 
+#define NCR5380_dma_xfer_len(instance, cmd, phase) \
+        generic_NCR5380_dma_xfer_len(cmd)
+
 #define NCR5380_intr generic_NCR5380_intr
 #define NCR5380_queue_command generic_NCR5380_queue_command
 #define NCR5380_abort generic_NCR5380_abort
Index: linux/drivers/scsi/dtc.h
===================================================================
--- linux.orig/drivers/scsi/dtc.h	2015-11-18 19:33:05.000000000 +1100
+++ linux/drivers/scsi/dtc.h	2015-11-18 19:33:35.000000000 +1100
@@ -27,6 +27,9 @@
 #define NCR5380_read(reg) (readb(DTC_address(reg)))
 #define NCR5380_write(reg, value) (writeb(value, DTC_address(reg)))
 
+#define NCR5380_dma_xfer_len(instance, cmd, phase) \
+        dtc_dma_xfer_len(cmd)
+
 #define NCR5380_intr			dtc_intr
 #define NCR5380_queue_command		dtc_queue_command
 #define NCR5380_abort			dtc_abort
Index: linux/drivers/scsi/arm/cumana_1.c
===================================================================
--- linux.orig/drivers/scsi/arm/cumana_1.c	2015-11-18 19:33:27.000000000 +1100
+++ linux/drivers/scsi/arm/cumana_1.c	2015-11-18 19:33:35.000000000 +1100
@@ -22,6 +22,9 @@
 #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)
+
+#define NCR5380_dma_xfer_len(instance, cmd, phase)	(cmd->transfersize)
+
 #define NCR5380_intr			cumanascsi_intr
 #define NCR5380_queue_command		cumanascsi_queue_command
 #define NCR5380_info			cumanascsi_info
Index: linux/drivers/scsi/arm/oak.c
===================================================================
--- linux.orig/drivers/scsi/arm/oak.c	2015-11-18 19:33:27.000000000 +1100
+++ linux/drivers/scsi/arm/oak.c	2015-11-18 19:33:35.000000000 +1100
@@ -26,6 +26,8 @@
 #define NCR5380_write(reg, value) \
 	writeb(value, priv(instance)->base + ((reg) << 2))
 
+#define NCR5380_dma_xfer_len(instance, cmd, phase)	(cmd->transfersize)
+
 #define NCR5380_queue_command		oakscsi_queue_command
 #define NCR5380_info			oakscsi_info
 #define NCR5380_show_info		oakscsi_show_info
Index: linux/drivers/scsi/mac_scsi.c
===================================================================
--- linux.orig/drivers/scsi/mac_scsi.c	2015-11-18 19:33:27.000000000 +1100
+++ linux/drivers/scsi/mac_scsi.c	2015-11-18 19:33:35.000000000 +1100
@@ -38,6 +38,7 @@
 
 #define NCR5380_pread                   macscsi_pread
 #define NCR5380_pwrite                  macscsi_pwrite
+#define NCR5380_dma_xfer_len(instance, cmd, phase)	(cmd->transfersize)
 
 #define NCR5380_intr                    macscsi_intr
 #define NCR5380_queue_command           macscsi_queue_command
Index: linux/drivers/scsi/pas16.h
===================================================================
--- linux.orig/drivers/scsi/pas16.h	2015-11-18 19:33:05.000000000 +1100
+++ linux/drivers/scsi/pas16.h	2015-11-18 19:33:35.000000000 +1100
@@ -110,6 +110,8 @@
 #define NCR5380_read(reg) ( inb(PAS16_io_port(reg)) )
 #define NCR5380_write(reg, value) ( outb((value),PAS16_io_port(reg)) )
 
+#define NCR5380_dma_xfer_len(instance, cmd, phase)	(cmd->transfersize)
+
 #define NCR5380_intr pas16_intr
 #define NCR5380_queue_command pas16_queue_command
 #define NCR5380_abort pas16_abort
Index: linux/drivers/scsi/t128.h
===================================================================
--- linux.orig/drivers/scsi/t128.h	2015-11-18 19:33:05.000000000 +1100
+++ linux/drivers/scsi/t128.h	2015-11-18 19:33:35.000000000 +1100
@@ -84,6 +84,8 @@
 #define NCR5380_read(reg) readb(T128_address(reg))
 #define NCR5380_write(reg, value) writeb((value),(T128_address(reg)))
 
+#define NCR5380_dma_xfer_len(instance, cmd, phase)	(cmd->transfersize)
+
 #define NCR5380_intr t128_intr
 #define NCR5380_queue_command t128_queue_command
 #define NCR5380_abort t128_abort

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

* [PATCH 24/71] ncr5380: Implement NCR5380_dma_xfer_len and remove LIMIT_TRANSFERSIZE macro
@ 2015-11-18  8:35   ` Finn Thain
  0 siblings, 0 replies; 268+ messages in thread
From: Finn Thain @ 2015-11-18  8:35 UTC (permalink / raw)
  To: linux-arm-kernel

An embedded and charset-unspecified text was scrubbed...
Name: ncr5380-implement-NCR5380_dma_xfer_len
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20151118/98f96b59/attachment.ksh>

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

* [PATCH 25/71] ncr5380: Rework disconnect versus poll logic
  2015-11-18  8:34 ` Finn Thain
@ 2015-11-18  8:35   ` Finn Thain
  -1 siblings, 0 replies; 268+ messages in thread
From: Finn Thain @ 2015-11-18  8:35 UTC (permalink / raw)
  To: James E.J. Bottomley, Michael Schmitz, linux-m68k, linux-scsi,
	linux-kernel

[-- Attachment #1: ncr5380-disconnection-reconnection --]
[-- Type: text/plain, Size: 16918 bytes --]

The atari_NCR5380.c and NCR5380.c core drivers differ in their handling of
target disconnection. This is partly because atari_NCR5380.c had all of
the polling and sleeping removed to become entirely interrupt-driven, and
it is partly because of damage done to NCR5380.c after atari_NCR5380.c was
forked. See commit 37cd23b44929 ("Linux 2.1.105") in history/history.git.

The polling changes that were made in v2.1.105 are questionable at best:
if REQ is not already asserted when NCR5380_transfer_pio() is invoked, and
if the expected phase is DATA IN or DATA OUT, the function will schedule
main() to execute after USLEEP_SLEEP jiffies and then return. The problems
here are the expected REQ timing and the sleep interval*. Avoid this issue
by using NCR5380_poll_politely() instead of scheduling main().

The atari_NCR5380.c core driver requires the use of the chip interrupt and
always permits target disconnection. It sets the cmd->device->disconnect
flag when a device disconnects, but never tests this flag.

The NCR5380.c core driver permits disconnection only when
instance->irq != NO_IRQ. It sets the cmd->device->disconnect flag when
a device disconnects and it tests this flag in a couple of places:

1. During NCR5380_information_transfer(), following COMMAND OUT phase,
   if !cmd->device->disconnect, the initiator will take a guess as to
   whether or not the target will then choose to go to MESSAGE IN phase
   and disconnect. If the driver guesses "yes", it will schedule main()
   to execute after USLEEP_SLEEP jiffies and then return there.

   Unfortunately the driver may guess "yes" even after it has denied
   the target the disconnection privilege. When the target does not
   disconnect, the sleep can be beneficial, assuming the sleep interval
   is appropriate (mostly it is not*).

   And even if the driver guesses "yes" correctly, and the target would
   then disconnect, the driver still has to go through the MESSAGE IN
   phase in order to get to BUS FREE phase. The main loop can do nothing
   useful until BUS FREE, and sleeping just delays the phase transition.

2. If !cmd->device->disconnect and REQ is not already asserted when
   NCR5380_information_transfer() is invoked, the function polls for REQ
   for USLEEP_POLL jiffies. If REQ is not asserted, it then schedules
   main() to execute after USLEEP_SLEEP jiffies and returns.

   The idea is apparently to yeild the CPU while waiting for REQ.
   This is conditional upon !cmd->device->disconnect, but there seems
   to be no rhyme or reason for that. For example, the flag may be
   unset because disconnection privilege was denied because the driver
   has no IRQ. Or the flag may be unset because the device has never
   needed to disconnect before. Or if the flag is set, disconnection
   may have no relevance to the present bus phase.

Another deficiency of the existing algorithm is as follows. When the
driver has no IRQ, it prevents disconnection, and generally polls and
sleeps more than it would normally. Now, if the driver is going to poll
anyway, why not allow the target to disconnect? That way the driver can do
something useful with the bus instead of polling unproductively!

Avoid this pointless latency, complexity and guesswork by using
NCR5380_poll_politely() instead of scheduling main().

* For g_NCR5380, the time intervals for USLEEP_SLEEP and USLEEP_POLL are
  200 ms and 10 ms, respectively. They are 20 ms and 200 ms respectively
  for the other NCR5380 drivers. There doesn't seem to be any reason for
  this discrepancy. The timing seems to have no relation to the type of
  adapter. Bizarrely, the timing in g_NCR5380 seems to relate only to one
  particular type of target device. This patch attempts to solve the
  problem for all NCR5380 drivers and all target devices.

Signed-off-by: Finn Thain <fthain@telegraphics.com.au>

---
 drivers/scsi/NCR5380.c       |  137 ++-----------------------------------------
 drivers/scsi/NCR5380.h       |   11 ---
 drivers/scsi/atari_NCR5380.c |   24 ++-----
 drivers/scsi/g_NCR5380.c     |    4 -
 4 files changed, 15 insertions(+), 161 deletions(-)

Index: linux/drivers/scsi/NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/NCR5380.c	2015-11-18 19:33:35.000000000 +1100
+++ linux/drivers/scsi/NCR5380.c	2015-11-18 19:33:38.000000000 +1100
@@ -139,17 +139,7 @@
  * 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.
- * 
- * The workaround for this is to keep track of devices that have
- * disconnected.  If the device hasn't disconnected, for commands that
- * should disconnect, we do something like 
- *
- * while (!REQ is asserted) { sleep for N usecs; poll for M usecs }
- * 
- * Some tweaking of N and M needs to be done.  An algorithm based 
- * on "time to data" would give the best results as long as short time
- * to datas (ie, on the same track) were considered, however these 
+ * 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.
  *
@@ -220,10 +210,6 @@
  * Defaults for these will be provided although the user may want to adjust 
  * these to allocate CPU resources to the SCSI driver or "real" code.
  * 
- * USLEEP_SLEEP - amount of time, in jiffies, to sleep
- *
- * USLEEP_POLL - amount of time, in jiffies, to poll
- *
  * These macros MUST be defined :
  * 
  * NCR5380_read(register)  - read from the specified register
@@ -458,73 +444,6 @@ static void NCR5380_print_phase(struct S
 }
 #endif
 
-/*
- * These need tweaking, and would probably work best as per-device 
- * flags initialized differently for disk, tape, cd, etc devices.
- * People with broken devices are free to experiment as to what gives
- * the best results for them.
- *
- * USLEEP_SLEEP should be a minimum seek time.
- *
- * USLEEP_POLL should be a maximum rotational latency.
- */
-#ifndef USLEEP_SLEEP
-/* 20 ms (reasonable hard disk speed) */
-#define USLEEP_SLEEP msecs_to_jiffies(20)
-#endif
-/* 300 RPM (floppy speed) */
-#ifndef USLEEP_POLL
-#define USLEEP_POLL msecs_to_jiffies(200)
-#endif
-
-/* 
- * Function : int should_disconnect (unsigned char cmd)
- *
- * Purpose : decide whether a command would normally disconnect or 
- *      not, since if it won't disconnect we should go to sleep.
- *
- * Input : cmd - opcode of SCSI command
- *
- * Returns : DISCONNECT_LONG if we should disconnect for a really long 
- *      time (ie always, sleep, look for REQ active, sleep), 
- *      DISCONNECT_TIME_TO_DATA if we would only disconnect for a normal
- *      time-to-data delay, DISCONNECT_NONE if this command would return
- *      immediately.
- *
- *      Future sleep algorithms based on time to data can exploit 
- *      something like this so they can differentiate between "normal" 
- *      (ie, read, write, seek) and unusual commands (ie, * format).
- *
- * Note : We don't deal with commands that handle an immediate disconnect,
- *        
- */
-
-static int should_disconnect(unsigned char cmd)
-{
-	switch (cmd) {
-	case READ_6:
-	case WRITE_6:
-	case SEEK_6:
-	case READ_10:
-	case WRITE_10:
-	case SEEK_10:
-		return DISCONNECT_TIME_TO_DATA;
-	case FORMAT_UNIT:
-	case SEARCH_HIGH:
-	case SEARCH_LOW:
-	case SEARCH_EQUAL:
-		return DISCONNECT_LONG;
-	default:
-		return DISCONNECT_NONE;
-	}
-}
-
-static void NCR5380_set_timer(struct NCR5380_hostdata *hostdata, unsigned long timeout)
-{
-	hostdata->time_expires = jiffies + timeout;
-	queue_delayed_work(hostdata->work_q, &hostdata->coroutine, timeout);
-}
-
 
 static int probe_irq __initdata;
 
@@ -623,9 +542,6 @@ static void prepare_info(struct Scsi_Hos
 	         "can_queue %d, cmd_per_lun %d, "
 	         "sg_tablesize %d, this_id %d, "
 	         "flags { %s%s%s%s}, "
-#if defined(USLEEP_POLL) && defined(USLEEP_SLEEP)
-		 "USLEEP_POLL %lu, USLEEP_SLEEP %lu, "
-#endif
 	         "options { %s} ",
 	         instance->hostt->name, instance->io_port, instance->n_io_port,
 	         instance->base, instance->irq,
@@ -635,9 +551,6 @@ static void prepare_info(struct Scsi_Hos
 	         hostdata->flags & FLAG_DTC3181E      ? "DTC3181E "      : "",
 	         hostdata->flags & FLAG_NO_PSEUDO_DMA ? "NO_PSEUDO_DMA " : "",
 	         hostdata->flags & FLAG_TOSHIBA_DELAY ? "TOSHIBA_DELAY "  : "",
-#if defined(USLEEP_POLL) && defined(USLEEP_SLEEP)
-	         USLEEP_POLL, USLEEP_SLEEP,
-#endif
 #ifdef AUTOPROBE_IRQ
 	         "AUTOPROBE_IRQ "
 #endif
@@ -812,7 +725,6 @@ static int NCR5380_init(struct Scsi_Host
 		hostdata->flags = FLAG_CHECK_LAST_BYTE_SENT | flags;
 
 	hostdata->host = instance;
-	hostdata->time_expires = 0;
 
 	prepare_info(instance);
 
@@ -1034,7 +946,6 @@ static void NCR5380_main(struct work_str
 #ifdef REAL_DMA
 		    && !hostdata->dmalen
 #endif
-		    && (!hostdata->time_expires || time_before_eq(hostdata->time_expires, jiffies))
 		    ) {
 			dprintk(NDEBUG_MAIN, "scsi%d : main() : performing information transfer\n", instance->host_no);
 			NCR5380_information_transfer(instance);
@@ -1414,11 +1325,6 @@ static int NCR5380_transfer_pio(struct S
 	unsigned char p = *phase, tmp;
 	int c = *count;
 	unsigned char *d = *data;
-	/*
-	 *      RvC: some administrative data to process polling time
-	 */
-	int break_allowed = 0;
-	struct NCR5380_hostdata *hostdata = (struct NCR5380_hostdata *) instance->hostdata;
 
 	if (!(p & SR_IO))
 		dprintk(NDEBUG_PIO, "scsi%d : pio write %d bytes\n", instance->host_no, c);
@@ -1433,35 +1339,19 @@ static int NCR5380_transfer_pio(struct S
 
 	 NCR5380_write(TARGET_COMMAND_REG, PHASE_SR_TO_TCR(p));
 
-	/* RvC: don't know if this is necessary, but other SCSI I/O is short
-	 *      so breaks are not necessary there
-	 */
-	if ((p == PHASE_DATAIN) || (p == PHASE_DATAOUT)) {
-		break_allowed = 1;
-	}
 	do {
 		/* 
 		 * Wait for assertion of REQ, after which the phase bits will be 
 		 * valid 
 		 */
 
-		/* RvC: we simply poll once, after that we stop temporarily
-		 *      and let the device buffer fill up
-		 *      if breaking is not allowed, we keep polling as long as needed
-		 */
-
-		/* FIXME */
-		while (!((tmp = NCR5380_read(STATUS_REG)) & SR_REQ) && !break_allowed);
-		if (!(tmp & SR_REQ)) {
-			/* timeout condition */
-			NCR5380_set_timer(hostdata, USLEEP_SLEEP);
+		if (NCR5380_poll_politely(instance, STATUS_REG, SR_REQ, SR_REQ, HZ) < 0)
 			break;
-		}
 
 		dprintk(NDEBUG_HANDSHAKE, "scsi%d : REQ detected\n", instance->host_no);
 
 		/* Check for phase mismatch */
-		if ((tmp & PHASE_MASK) != p) {
+		if ((NCR5380_read(STATUS_REG) & PHASE_MASK) != p) {
 			dprintk(NDEBUG_HANDSHAKE, "scsi%d : phase mismatch\n", instance->host_no);
 			NCR5380_dprint_phase(NDEBUG_HANDSHAKE, instance);
 			break;
@@ -1933,8 +1823,6 @@ static void NCR5380_information_transfer
 	unsigned char *data;
 	unsigned char phase, tmp, extended_msg[10], old_phase = 0xff;
 	struct scsi_cmnd *cmd = (struct scsi_cmnd *) hostdata->connected;
-	/* RvC: we need to set the end of the polling time */
-	unsigned long poll_time = jiffies + USLEEP_POLL;
 
 	while (1) {
 		tmp = NCR5380_read(STATUS_REG);
@@ -2134,7 +2022,6 @@ static void NCR5380_information_transfer
 				case DISCONNECT:{
 						/* Accept message by clearing ACK */
 						NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
-						cmd->device->disconnect = 1;
 						LIST(cmd, hostdata->disconnected_queue);
 						cmd->host_scribble = (unsigned char *)
 						    hostdata->disconnected_queue;
@@ -2266,11 +2153,6 @@ static void NCR5380_information_transfer
 				 * use the dma transfer function.  
 				 */
 				NCR5380_transfer_pio(instance, &phase, &len, &data);
-				if (!cmd->device->disconnect && should_disconnect(cmd->cmnd[0])) {
-					NCR5380_set_timer(hostdata, USLEEP_SLEEP);
-					dprintk(NDEBUG_USLEEP, "scsi%d : issued command, sleeping until %lu\n", instance->host_no, hostdata->time_expires);
-					return;
-				}
 				break;
 			case PHASE_STATIN:
 				len = 1;
@@ -2282,15 +2164,10 @@ static void NCR5380_information_transfer
 				printk("scsi%d : unknown phase\n", instance->host_no);
 				NCR5380_dprint(NDEBUG_ANY, instance);
 			}	/* switch(phase) */
-		}		/* if (tmp * SR_REQ) */
-		else {
-			/* RvC: go to sleep if polling time expired
-			 */
-			if (!cmd->device->disconnect && time_after_eq(jiffies, poll_time)) {
-				NCR5380_set_timer(hostdata, USLEEP_SLEEP);
-				dprintk(NDEBUG_USLEEP, "scsi%d : poll timed out, sleeping until %lu\n", instance->host_no, hostdata->time_expires);
-				return;
-			}
+		} else {
+			spin_unlock_irq(instance->host_lock);
+			NCR5380_poll_politely(instance, STATUS_REG, SR_REQ, SR_REQ, HZ);
+			spin_lock_irq(instance->host_lock);
 		}
 	}			/* while (1) */
 }
Index: linux/drivers/scsi/NCR5380.h
===================================================================
--- linux.orig/drivers/scsi/NCR5380.h	2015-11-18 19:33:33.000000000 +1100
+++ linux/drivers/scsi/NCR5380.h	2015-11-18 19:33:38.000000000 +1100
@@ -205,16 +205,6 @@
 
 #define PHASE_SR_TO_TCR(phase) ((phase) >> 2)
 
-/*
- * The internal should_disconnect() function returns these based on the 
- * expected length of a disconnect if a device supports disconnect/
- * reconnect.
- */
-
-#define DISCONNECT_NONE		0
-#define DISCONNECT_TIME_TO_DATA	1
-#define DISCONNECT_LONG		2
-
 /* 
  * "Special" value for the (unsigned char) command tag, to indicate
  * I_T_L nexus instead of I_T_L_Q.
@@ -266,7 +256,6 @@ struct NCR5380_hostdata {
 	volatile struct scsi_cmnd *issue_queue;	/* waiting to be issued */
 	volatile struct scsi_cmnd *disconnected_queue;	/* waiting for reconnect */
 	int flags;
-	unsigned long time_expires;		/* in jiffies, set prior to sleeping */
 	struct delayed_work coroutine;		/* our co-routine */
 	struct scsi_eh_save ses;
 	char info[256];
Index: linux/drivers/scsi/atari_NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/atari_NCR5380.c	2015-11-18 19:33:35.000000000 +1100
+++ linux/drivers/scsi/atari_NCR5380.c	2015-11-18 19:33:38.000000000 +1100
@@ -126,17 +126,7 @@
  * 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.
- *
- * The workaround for this is to keep track of devices that have
- * disconnected.  If the device hasn't disconnected, for commands that
- * should disconnect, we do something like
- *
- * while (!REQ is asserted) { sleep for N usecs; poll for M usecs }
- *
- * Some tweaking of N and M needs to be done.  An algorithm based
- * on "time to data" would give the best results as long as short time
- * to datas (ie, on the same track) were considered, however these
+ * 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.
  *
@@ -1734,13 +1724,14 @@ static int NCR5380_transfer_pio(struct S
 		 * Wait for assertion of REQ, after which the phase bits will be
 		 * valid
 		 */
-		while (!((tmp = NCR5380_read(STATUS_REG)) & SR_REQ))
-			;
+
+		if (NCR5380_poll_politely(instance, STATUS_REG, SR_REQ, SR_REQ, HZ) < 0)
+			break;
 
 		dprintk(NDEBUG_HANDSHAKE, "scsi%d: REQ detected\n", HOSTNO);
 
 		/* Check for phase mismatch */
-		if ((tmp & PHASE_MASK) != p) {
+		if ((NCR5380_read(STATUS_REG) & PHASE_MASK) != p) {
 			dprintk(NDEBUG_PIO, "scsi%d: phase mismatch\n", HOSTNO);
 			NCR5380_dprint_phase(NDEBUG_PIO, instance);
 			break;
@@ -2393,7 +2384,6 @@ static void NCR5380_information_transfer
 					/* Accept message by clearing ACK */
 					NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
 					local_irq_save(flags);
-					cmd->device->disconnect = 1;
 					LIST(cmd,hostdata->disconnected_queue);
 					SET_NEXT(cmd, hostdata->disconnected_queue);
 					hostdata->connected = NULL;
@@ -2558,7 +2548,9 @@ static void NCR5380_information_transfer
 				printk("scsi%d: unknown phase\n", HOSTNO);
 				NCR5380_dprint(NDEBUG_ANY, instance);
 			} /* switch(phase) */
-		} /* if (tmp * SR_REQ) */
+		} else {
+			NCR5380_poll_politely(instance, STATUS_REG, SR_REQ, SR_REQ, HZ);
+		}
 	} /* while (1) */
 }
 
Index: linux/drivers/scsi/g_NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/g_NCR5380.c	2015-11-18 19:33:35.000000000 +1100
+++ linux/drivers/scsi/g_NCR5380.c	2015-11-18 19:33:38.000000000 +1100
@@ -56,10 +56,6 @@
  *     
  */
 
-/* settings for DTC3181E card with only Mustek scanner attached */
-#define USLEEP_POLL	msecs_to_jiffies(10)
-#define USLEEP_SLEEP	msecs_to_jiffies(200)
-
 #define AUTOPROBE_IRQ
 
 #ifdef CONFIG_SCSI_GENERIC_NCR53C400



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

* [PATCH 25/71] ncr5380: Rework disconnect versus poll logic
@ 2015-11-18  8:35   ` Finn Thain
  0 siblings, 0 replies; 268+ messages in thread
From: Finn Thain @ 2015-11-18  8:35 UTC (permalink / raw)
  To: James E.J. Bottomley, Michael Schmitz, linux-m68k, linux-scsi,
	linux-kernel

[-- Attachment #1: ncr5380-disconnection-reconnection --]
[-- Type: text/plain, Size: 16916 bytes --]

The atari_NCR5380.c and NCR5380.c core drivers differ in their handling of
target disconnection. This is partly because atari_NCR5380.c had all of
the polling and sleeping removed to become entirely interrupt-driven, and
it is partly because of damage done to NCR5380.c after atari_NCR5380.c was
forked. See commit 37cd23b44929 ("Linux 2.1.105") in history/history.git.

The polling changes that were made in v2.1.105 are questionable at best:
if REQ is not already asserted when NCR5380_transfer_pio() is invoked, and
if the expected phase is DATA IN or DATA OUT, the function will schedule
main() to execute after USLEEP_SLEEP jiffies and then return. The problems
here are the expected REQ timing and the sleep interval*. Avoid this issue
by using NCR5380_poll_politely() instead of scheduling main().

The atari_NCR5380.c core driver requires the use of the chip interrupt and
always permits target disconnection. It sets the cmd->device->disconnect
flag when a device disconnects, but never tests this flag.

The NCR5380.c core driver permits disconnection only when
instance->irq != NO_IRQ. It sets the cmd->device->disconnect flag when
a device disconnects and it tests this flag in a couple of places:

1. During NCR5380_information_transfer(), following COMMAND OUT phase,
   if !cmd->device->disconnect, the initiator will take a guess as to
   whether or not the target will then choose to go to MESSAGE IN phase
   and disconnect. If the driver guesses "yes", it will schedule main()
   to execute after USLEEP_SLEEP jiffies and then return there.

   Unfortunately the driver may guess "yes" even after it has denied
   the target the disconnection privilege. When the target does not
   disconnect, the sleep can be beneficial, assuming the sleep interval
   is appropriate (mostly it is not*).

   And even if the driver guesses "yes" correctly, and the target would
   then disconnect, the driver still has to go through the MESSAGE IN
   phase in order to get to BUS FREE phase. The main loop can do nothing
   useful until BUS FREE, and sleeping just delays the phase transition.

2. If !cmd->device->disconnect and REQ is not already asserted when
   NCR5380_information_transfer() is invoked, the function polls for REQ
   for USLEEP_POLL jiffies. If REQ is not asserted, it then schedules
   main() to execute after USLEEP_SLEEP jiffies and returns.

   The idea is apparently to yeild the CPU while waiting for REQ.
   This is conditional upon !cmd->device->disconnect, but there seems
   to be no rhyme or reason for that. For example, the flag may be
   unset because disconnection privilege was denied because the driver
   has no IRQ. Or the flag may be unset because the device has never
   needed to disconnect before. Or if the flag is set, disconnection
   may have no relevance to the present bus phase.

Another deficiency of the existing algorithm is as follows. When the
driver has no IRQ, it prevents disconnection, and generally polls and
sleeps more than it would normally. Now, if the driver is going to poll
anyway, why not allow the target to disconnect? That way the driver can do
something useful with the bus instead of polling unproductively!

Avoid this pointless latency, complexity and guesswork by using
NCR5380_poll_politely() instead of scheduling main().

* For g_NCR5380, the time intervals for USLEEP_SLEEP and USLEEP_POLL are
  200 ms and 10 ms, respectively. They are 20 ms and 200 ms respectively
  for the other NCR5380 drivers. There doesn't seem to be any reason for
  this discrepancy. The timing seems to have no relation to the type of
  adapter. Bizarrely, the timing in g_NCR5380 seems to relate only to one
  particular type of target device. This patch attempts to solve the
  problem for all NCR5380 drivers and all target devices.

Signed-off-by: Finn Thain <fthain@telegraphics.com.au>

---
 drivers/scsi/NCR5380.c       |  137 ++-----------------------------------------
 drivers/scsi/NCR5380.h       |   11 ---
 drivers/scsi/atari_NCR5380.c |   24 ++-----
 drivers/scsi/g_NCR5380.c     |    4 -
 4 files changed, 15 insertions(+), 161 deletions(-)

Index: linux/drivers/scsi/NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/NCR5380.c	2015-11-18 19:33:35.000000000 +1100
+++ linux/drivers/scsi/NCR5380.c	2015-11-18 19:33:38.000000000 +1100
@@ -139,17 +139,7 @@
  * 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.
- * 
- * The workaround for this is to keep track of devices that have
- * disconnected.  If the device hasn't disconnected, for commands that
- * should disconnect, we do something like 
- *
- * while (!REQ is asserted) { sleep for N usecs; poll for M usecs }
- * 
- * Some tweaking of N and M needs to be done.  An algorithm based 
- * on "time to data" would give the best results as long as short time
- * to datas (ie, on the same track) were considered, however these 
+ * 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.
  *
@@ -220,10 +210,6 @@
  * Defaults for these will be provided although the user may want to adjust 
  * these to allocate CPU resources to the SCSI driver or "real" code.
  * 
- * USLEEP_SLEEP - amount of time, in jiffies, to sleep
- *
- * USLEEP_POLL - amount of time, in jiffies, to poll
- *
  * These macros MUST be defined :
  * 
  * NCR5380_read(register)  - read from the specified register
@@ -458,73 +444,6 @@ static void NCR5380_print_phase(struct S
 }
 #endif
 
-/*
- * These need tweaking, and would probably work best as per-device 
- * flags initialized differently for disk, tape, cd, etc devices.
- * People with broken devices are free to experiment as to what gives
- * the best results for them.
- *
- * USLEEP_SLEEP should be a minimum seek time.
- *
- * USLEEP_POLL should be a maximum rotational latency.
- */
-#ifndef USLEEP_SLEEP
-/* 20 ms (reasonable hard disk speed) */
-#define USLEEP_SLEEP msecs_to_jiffies(20)
-#endif
-/* 300 RPM (floppy speed) */
-#ifndef USLEEP_POLL
-#define USLEEP_POLL msecs_to_jiffies(200)
-#endif
-
-/* 
- * Function : int should_disconnect (unsigned char cmd)
- *
- * Purpose : decide whether a command would normally disconnect or 
- *      not, since if it won't disconnect we should go to sleep.
- *
- * Input : cmd - opcode of SCSI command
- *
- * Returns : DISCONNECT_LONG if we should disconnect for a really long 
- *      time (ie always, sleep, look for REQ active, sleep), 
- *      DISCONNECT_TIME_TO_DATA if we would only disconnect for a normal
- *      time-to-data delay, DISCONNECT_NONE if this command would return
- *      immediately.
- *
- *      Future sleep algorithms based on time to data can exploit 
- *      something like this so they can differentiate between "normal" 
- *      (ie, read, write, seek) and unusual commands (ie, * format).
- *
- * Note : We don't deal with commands that handle an immediate disconnect,
- *        
- */
-
-static int should_disconnect(unsigned char cmd)
-{
-	switch (cmd) {
-	case READ_6:
-	case WRITE_6:
-	case SEEK_6:
-	case READ_10:
-	case WRITE_10:
-	case SEEK_10:
-		return DISCONNECT_TIME_TO_DATA;
-	case FORMAT_UNIT:
-	case SEARCH_HIGH:
-	case SEARCH_LOW:
-	case SEARCH_EQUAL:
-		return DISCONNECT_LONG;
-	default:
-		return DISCONNECT_NONE;
-	}
-}
-
-static void NCR5380_set_timer(struct NCR5380_hostdata *hostdata, unsigned long timeout)
-{
-	hostdata->time_expires = jiffies + timeout;
-	queue_delayed_work(hostdata->work_q, &hostdata->coroutine, timeout);
-}
-
 
 static int probe_irq __initdata;
 
@@ -623,9 +542,6 @@ static void prepare_info(struct Scsi_Hos
 	         "can_queue %d, cmd_per_lun %d, "
 	         "sg_tablesize %d, this_id %d, "
 	         "flags { %s%s%s%s}, "
-#if defined(USLEEP_POLL) && defined(USLEEP_SLEEP)
-		 "USLEEP_POLL %lu, USLEEP_SLEEP %lu, "
-#endif
 	         "options { %s} ",
 	         instance->hostt->name, instance->io_port, instance->n_io_port,
 	         instance->base, instance->irq,
@@ -635,9 +551,6 @@ static void prepare_info(struct Scsi_Hos
 	         hostdata->flags & FLAG_DTC3181E      ? "DTC3181E "      : "",
 	         hostdata->flags & FLAG_NO_PSEUDO_DMA ? "NO_PSEUDO_DMA " : "",
 	         hostdata->flags & FLAG_TOSHIBA_DELAY ? "TOSHIBA_DELAY "  : "",
-#if defined(USLEEP_POLL) && defined(USLEEP_SLEEP)
-	         USLEEP_POLL, USLEEP_SLEEP,
-#endif
 #ifdef AUTOPROBE_IRQ
 	         "AUTOPROBE_IRQ "
 #endif
@@ -812,7 +725,6 @@ static int NCR5380_init(struct Scsi_Host
 		hostdata->flags = FLAG_CHECK_LAST_BYTE_SENT | flags;
 
 	hostdata->host = instance;
-	hostdata->time_expires = 0;
 
 	prepare_info(instance);
 
@@ -1034,7 +946,6 @@ static void NCR5380_main(struct work_str
 #ifdef REAL_DMA
 		    && !hostdata->dmalen
 #endif
-		    && (!hostdata->time_expires || time_before_eq(hostdata->time_expires, jiffies))
 		    ) {
 			dprintk(NDEBUG_MAIN, "scsi%d : main() : performing information transfer\n", instance->host_no);
 			NCR5380_information_transfer(instance);
@@ -1414,11 +1325,6 @@ static int NCR5380_transfer_pio(struct S
 	unsigned char p = *phase, tmp;
 	int c = *count;
 	unsigned char *d = *data;
-	/*
-	 *      RvC: some administrative data to process polling time
-	 */
-	int break_allowed = 0;
-	struct NCR5380_hostdata *hostdata = (struct NCR5380_hostdata *) instance->hostdata;
 
 	if (!(p & SR_IO))
 		dprintk(NDEBUG_PIO, "scsi%d : pio write %d bytes\n", instance->host_no, c);
@@ -1433,35 +1339,19 @@ static int NCR5380_transfer_pio(struct S
 
 	 NCR5380_write(TARGET_COMMAND_REG, PHASE_SR_TO_TCR(p));
 
-	/* RvC: don't know if this is necessary, but other SCSI I/O is short
-	 *      so breaks are not necessary there
-	 */
-	if ((p == PHASE_DATAIN) || (p == PHASE_DATAOUT)) {
-		break_allowed = 1;
-	}
 	do {
 		/* 
 		 * Wait for assertion of REQ, after which the phase bits will be 
 		 * valid 
 		 */
 
-		/* RvC: we simply poll once, after that we stop temporarily
-		 *      and let the device buffer fill up
-		 *      if breaking is not allowed, we keep polling as long as needed
-		 */
-
-		/* FIXME */
-		while (!((tmp = NCR5380_read(STATUS_REG)) & SR_REQ) && !break_allowed);
-		if (!(tmp & SR_REQ)) {
-			/* timeout condition */
-			NCR5380_set_timer(hostdata, USLEEP_SLEEP);
+		if (NCR5380_poll_politely(instance, STATUS_REG, SR_REQ, SR_REQ, HZ) < 0)
 			break;
-		}
 
 		dprintk(NDEBUG_HANDSHAKE, "scsi%d : REQ detected\n", instance->host_no);
 
 		/* Check for phase mismatch */
-		if ((tmp & PHASE_MASK) != p) {
+		if ((NCR5380_read(STATUS_REG) & PHASE_MASK) != p) {
 			dprintk(NDEBUG_HANDSHAKE, "scsi%d : phase mismatch\n", instance->host_no);
 			NCR5380_dprint_phase(NDEBUG_HANDSHAKE, instance);
 			break;
@@ -1933,8 +1823,6 @@ static void NCR5380_information_transfer
 	unsigned char *data;
 	unsigned char phase, tmp, extended_msg[10], old_phase = 0xff;
 	struct scsi_cmnd *cmd = (struct scsi_cmnd *) hostdata->connected;
-	/* RvC: we need to set the end of the polling time */
-	unsigned long poll_time = jiffies + USLEEP_POLL;
 
 	while (1) {
 		tmp = NCR5380_read(STATUS_REG);
@@ -2134,7 +2022,6 @@ static void NCR5380_information_transfer
 				case DISCONNECT:{
 						/* Accept message by clearing ACK */
 						NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
-						cmd->device->disconnect = 1;
 						LIST(cmd, hostdata->disconnected_queue);
 						cmd->host_scribble = (unsigned char *)
 						    hostdata->disconnected_queue;
@@ -2266,11 +2153,6 @@ static void NCR5380_information_transfer
 				 * use the dma transfer function.  
 				 */
 				NCR5380_transfer_pio(instance, &phase, &len, &data);
-				if (!cmd->device->disconnect && should_disconnect(cmd->cmnd[0])) {
-					NCR5380_set_timer(hostdata, USLEEP_SLEEP);
-					dprintk(NDEBUG_USLEEP, "scsi%d : issued command, sleeping until %lu\n", instance->host_no, hostdata->time_expires);
-					return;
-				}
 				break;
 			case PHASE_STATIN:
 				len = 1;
@@ -2282,15 +2164,10 @@ static void NCR5380_information_transfer
 				printk("scsi%d : unknown phase\n", instance->host_no);
 				NCR5380_dprint(NDEBUG_ANY, instance);
 			}	/* switch(phase) */
-		}		/* if (tmp * SR_REQ) */
-		else {
-			/* RvC: go to sleep if polling time expired
-			 */
-			if (!cmd->device->disconnect && time_after_eq(jiffies, poll_time)) {
-				NCR5380_set_timer(hostdata, USLEEP_SLEEP);
-				dprintk(NDEBUG_USLEEP, "scsi%d : poll timed out, sleeping until %lu\n", instance->host_no, hostdata->time_expires);
-				return;
-			}
+		} else {
+			spin_unlock_irq(instance->host_lock);
+			NCR5380_poll_politely(instance, STATUS_REG, SR_REQ, SR_REQ, HZ);
+			spin_lock_irq(instance->host_lock);
 		}
 	}			/* while (1) */
 }
Index: linux/drivers/scsi/NCR5380.h
===================================================================
--- linux.orig/drivers/scsi/NCR5380.h	2015-11-18 19:33:33.000000000 +1100
+++ linux/drivers/scsi/NCR5380.h	2015-11-18 19:33:38.000000000 +1100
@@ -205,16 +205,6 @@
 
 #define PHASE_SR_TO_TCR(phase) ((phase) >> 2)
 
-/*
- * The internal should_disconnect() function returns these based on the 
- * expected length of a disconnect if a device supports disconnect/
- * reconnect.
- */
-
-#define DISCONNECT_NONE		0
-#define DISCONNECT_TIME_TO_DATA	1
-#define DISCONNECT_LONG		2
-
 /* 
  * "Special" value for the (unsigned char) command tag, to indicate
  * I_T_L nexus instead of I_T_L_Q.
@@ -266,7 +256,6 @@ struct NCR5380_hostdata {
 	volatile struct scsi_cmnd *issue_queue;	/* waiting to be issued */
 	volatile struct scsi_cmnd *disconnected_queue;	/* waiting for reconnect */
 	int flags;
-	unsigned long time_expires;		/* in jiffies, set prior to sleeping */
 	struct delayed_work coroutine;		/* our co-routine */
 	struct scsi_eh_save ses;
 	char info[256];
Index: linux/drivers/scsi/atari_NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/atari_NCR5380.c	2015-11-18 19:33:35.000000000 +1100
+++ linux/drivers/scsi/atari_NCR5380.c	2015-11-18 19:33:38.000000000 +1100
@@ -126,17 +126,7 @@
  * 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.
- *
- * The workaround for this is to keep track of devices that have
- * disconnected.  If the device hasn't disconnected, for commands that
- * should disconnect, we do something like
- *
- * while (!REQ is asserted) { sleep for N usecs; poll for M usecs }
- *
- * Some tweaking of N and M needs to be done.  An algorithm based
- * on "time to data" would give the best results as long as short time
- * to datas (ie, on the same track) were considered, however these
+ * 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.
  *
@@ -1734,13 +1724,14 @@ static int NCR5380_transfer_pio(struct S
 		 * Wait for assertion of REQ, after which the phase bits will be
 		 * valid
 		 */
-		while (!((tmp = NCR5380_read(STATUS_REG)) & SR_REQ))
-			;
+
+		if (NCR5380_poll_politely(instance, STATUS_REG, SR_REQ, SR_REQ, HZ) < 0)
+			break;
 
 		dprintk(NDEBUG_HANDSHAKE, "scsi%d: REQ detected\n", HOSTNO);
 
 		/* Check for phase mismatch */
-		if ((tmp & PHASE_MASK) != p) {
+		if ((NCR5380_read(STATUS_REG) & PHASE_MASK) != p) {
 			dprintk(NDEBUG_PIO, "scsi%d: phase mismatch\n", HOSTNO);
 			NCR5380_dprint_phase(NDEBUG_PIO, instance);
 			break;
@@ -2393,7 +2384,6 @@ static void NCR5380_information_transfer
 					/* Accept message by clearing ACK */
 					NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
 					local_irq_save(flags);
-					cmd->device->disconnect = 1;
 					LIST(cmd,hostdata->disconnected_queue);
 					SET_NEXT(cmd, hostdata->disconnected_queue);
 					hostdata->connected = NULL;
@@ -2558,7 +2548,9 @@ static void NCR5380_information_transfer
 				printk("scsi%d: unknown phase\n", HOSTNO);
 				NCR5380_dprint(NDEBUG_ANY, instance);
 			} /* switch(phase) */
-		} /* if (tmp * SR_REQ) */
+		} else {
+			NCR5380_poll_politely(instance, STATUS_REG, SR_REQ, SR_REQ, HZ);
+		}
 	} /* while (1) */
 }
 
Index: linux/drivers/scsi/g_NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/g_NCR5380.c	2015-11-18 19:33:35.000000000 +1100
+++ linux/drivers/scsi/g_NCR5380.c	2015-11-18 19:33:38.000000000 +1100
@@ -56,10 +56,6 @@
  *     
  */
 
-/* settings for DTC3181E card with only Mustek scanner attached */
-#define USLEEP_POLL	msecs_to_jiffies(10)
-#define USLEEP_SLEEP	msecs_to_jiffies(200)
-
 #define AUTOPROBE_IRQ
 
 #ifdef CONFIG_SCSI_GENERIC_NCR53C400

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

* [PATCH 26/71] ncr5380: Fix NCR5380_transfer_pio() result
  2015-11-18  8:34 ` Finn Thain
@ 2015-11-18  8:35   ` Finn Thain
  -1 siblings, 0 replies; 268+ messages in thread
From: Finn Thain @ 2015-11-18  8:35 UTC (permalink / raw)
  To: James E.J. Bottomley, Michael Schmitz, linux-m68k, linux-scsi,
	linux-kernel

[-- Attachment #1: ncr5380-fix-transfer_pio --]
[-- Type: text/plain, Size: 3243 bytes --]

According to the SCSI-2 draft revision 10L, atari_NCR5380.c is correct
when it says that the phase lines are valid up until ACK is negated
following the transmission of the last byte in MESSAGE IN phase. This is
true for all information transfer phases, from target to initiator.

Sample the phase bits in STATUS_REG so that NCR5380_transfer_pio() can
return the correct result. The return value is presently unused (perhaps
because of bugs like this) but this change at least fixes the caller's
phase variable, which is passed by reference.

Signed-off-by: Finn Thain <fthain@telegraphics.com.au>

---
 drivers/scsi/NCR5380.c       |   12 +++++++++---
 drivers/scsi/atari_NCR5380.c |   11 ++++++-----
 2 files changed, 15 insertions(+), 8 deletions(-)

Index: linux/drivers/scsi/NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/NCR5380.c	2015-11-18 19:33:38.000000000 +1100
+++ linux/drivers/scsi/NCR5380.c	2015-11-18 19:33:39.000000000 +1100
@@ -1386,8 +1386,10 @@ static int NCR5380_transfer_pio(struct S
 			NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_ACK);
 		}
 
-		/* FIXME - if this fails bus reset ?? */
-		NCR5380_poll_politely(instance, STATUS_REG, SR_REQ, 0, 5*HZ);
+		if (NCR5380_poll_politely(instance,
+		                          STATUS_REG, SR_REQ, 0, 5 * HZ) < 0)
+			break;
+
 		dprintk(NDEBUG_HANDSHAKE, "scsi%d : req false, handshake complete\n", instance->host_no);
 
 /*
@@ -1414,7 +1416,11 @@ static int NCR5380_transfer_pio(struct S
 	*count = c;
 	*data = d;
 	tmp = NCR5380_read(STATUS_REG);
-	if (tmp & SR_REQ)
+	/* 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;
Index: linux/drivers/scsi/atari_NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/atari_NCR5380.c	2015-11-18 19:33:38.000000000 +1100
+++ linux/drivers/scsi/atari_NCR5380.c	2015-11-18 19:33:39.000000000 +1100
@@ -1770,8 +1770,9 @@ static int NCR5380_transfer_pio(struct S
 			NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_ACK);
 		}
 
-		while (NCR5380_read(STATUS_REG) & SR_REQ)
-			;
+		if (NCR5380_poll_politely(instance,
+		                          STATUS_REG, SR_REQ, 0, 5 * HZ) < 0)
+			break;
 
 		dprintk(NDEBUG_HANDSHAKE, "scsi%d: req false, handshake complete\n", HOSTNO);
 
@@ -1800,10 +1801,10 @@ static int NCR5380_transfer_pio(struct S
 	*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 is the case if
-	 * we're in MSGIN and all wanted bytes have been received.
+	 * 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) || (p == PHASE_MSGIN && c == 0))
+	if ((tmp & SR_REQ) || ((tmp & SR_IO) && c == 0))
 		*phase = tmp & PHASE_MASK;
 	else
 		*phase = PHASE_UNKNOWN;



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

* [PATCH 26/71] ncr5380: Fix NCR5380_transfer_pio() result
@ 2015-11-18  8:35   ` Finn Thain
  0 siblings, 0 replies; 268+ messages in thread
From: Finn Thain @ 2015-11-18  8:35 UTC (permalink / raw)
  To: James E.J. Bottomley, Michael Schmitz, linux-m68k, linux-scsi,
	linux-kernel

[-- Attachment #1: ncr5380-fix-transfer_pio --]
[-- Type: text/plain, Size: 3241 bytes --]

According to the SCSI-2 draft revision 10L, atari_NCR5380.c is correct
when it says that the phase lines are valid up until ACK is negated
following the transmission of the last byte in MESSAGE IN phase. This is
true for all information transfer phases, from target to initiator.

Sample the phase bits in STATUS_REG so that NCR5380_transfer_pio() can
return the correct result. The return value is presently unused (perhaps
because of bugs like this) but this change at least fixes the caller's
phase variable, which is passed by reference.

Signed-off-by: Finn Thain <fthain@telegraphics.com.au>

---
 drivers/scsi/NCR5380.c       |   12 +++++++++---
 drivers/scsi/atari_NCR5380.c |   11 ++++++-----
 2 files changed, 15 insertions(+), 8 deletions(-)

Index: linux/drivers/scsi/NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/NCR5380.c	2015-11-18 19:33:38.000000000 +1100
+++ linux/drivers/scsi/NCR5380.c	2015-11-18 19:33:39.000000000 +1100
@@ -1386,8 +1386,10 @@ static int NCR5380_transfer_pio(struct S
 			NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_ACK);
 		}
 
-		/* FIXME - if this fails bus reset ?? */
-		NCR5380_poll_politely(instance, STATUS_REG, SR_REQ, 0, 5*HZ);
+		if (NCR5380_poll_politely(instance,
+		                          STATUS_REG, SR_REQ, 0, 5 * HZ) < 0)
+			break;
+
 		dprintk(NDEBUG_HANDSHAKE, "scsi%d : req false, handshake complete\n", instance->host_no);
 
 /*
@@ -1414,7 +1416,11 @@ static int NCR5380_transfer_pio(struct S
 	*count = c;
 	*data = d;
 	tmp = NCR5380_read(STATUS_REG);
-	if (tmp & SR_REQ)
+	/* 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;
Index: linux/drivers/scsi/atari_NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/atari_NCR5380.c	2015-11-18 19:33:38.000000000 +1100
+++ linux/drivers/scsi/atari_NCR5380.c	2015-11-18 19:33:39.000000000 +1100
@@ -1770,8 +1770,9 @@ static int NCR5380_transfer_pio(struct S
 			NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_ACK);
 		}
 
-		while (NCR5380_read(STATUS_REG) & SR_REQ)
-			;
+		if (NCR5380_poll_politely(instance,
+		                          STATUS_REG, SR_REQ, 0, 5 * HZ) < 0)
+			break;
 
 		dprintk(NDEBUG_HANDSHAKE, "scsi%d: req false, handshake complete\n", HOSTNO);
 
@@ -1800,10 +1801,10 @@ static int NCR5380_transfer_pio(struct S
 	*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 is the case if
-	 * we're in MSGIN and all wanted bytes have been received.
+	 * 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) || (p == PHASE_MSGIN && c == 0))
+	if ((tmp & SR_REQ) || ((tmp & SR_IO) && c == 0))
 		*phase = tmp & PHASE_MASK;
 	else
 		*phase = PHASE_UNKNOWN;

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

* [PATCH 27/71] ncr5380: Add missing lock in eh_abort_handler
  2015-11-18  8:34 ` Finn Thain
@ 2015-11-18  8:35   ` Finn Thain
  -1 siblings, 0 replies; 268+ messages in thread
From: Finn Thain @ 2015-11-18  8:35 UTC (permalink / raw)
  To: James E.J. Bottomley, Michael Schmitz, linux-m68k, linux-scsi,
	linux-kernel

[-- Attachment #1: ncr5380-spin_unlock-crash --]
[-- Type: text/plain, Size: 3490 bytes --]

The host spin lock needs to be acquired by NCR5380_abort() before it calls
NCR5380_select(). This patch doesn't actually fix the EH issues in this
driver but it does avoid this:

BUG: spinlock already unlocked on CPU#0, kworker/u4:1/14
 lock: 0xc0c0f834, .magic: dead4ead, .owner: <none>/-1, .owner_cpu: -1
 CPU: 0 PID: 14 Comm: kworker/u4:1 Not tainted 3.15.5 #5
 Workqueue: scsi_tmf_4 scmd_eh_abort_handler
 Call Trace:
 [ef885d70] [c0008acc] show_stack+0x70/0x1bc (unreliable)
 [ef885db0] [c0492a00] dump_stack+0x84/0x684
 [ef885dc0] [c006f314] spin_dump+0xd0/0xe8
 [ef885dd0] [c006f460] do_raw_spin_unlock+0xd4/0xd8
 [ef885df0] [c0491c8c] _raw_spin_unlock_irq+0x10/0x3c
 [ef885e00] [f381fe3c] NCR5380_select+0x3e4/0x6e8 [dmx3191d]
 [ef885e40] [f382026c] NCR5380_abort+0x12c/0x190 [dmx3191d]
 [ef885e60] [c02fec9c] scmd_eh_abort_handler+0x100/0x460
 [ef885e80] [c0046470] process_one_work+0x16c/0x420
 [ef885ea0] [c0046870] worker_thread+0x14c/0x430
 [ef885ed0] [c004e4f4] kthread+0xd8/0xec
 [ef885f40] [c00124d4] ret_from_kernel_thread+0x5c/0x64

Signed-off-by: Finn Thain <fthain@telegraphics.com.au>

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

Index: linux/drivers/scsi/NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/NCR5380.c	2015-11-18 19:33:39.000000000 +1100
+++ linux/drivers/scsi/NCR5380.c	2015-11-18 19:33:40.000000000 +1100
@@ -2367,6 +2367,7 @@ static int NCR5380_abort(struct scsi_cmn
 
 	scmd_printk(KERN_WARNING, cmd, "aborting command\n");
 
+	spin_lock_irq(instance->host_lock);
 	NCR5380_print_status(instance);
 
 	dprintk(NDEBUG_ABORT, "scsi%d : abort called\n", instance->host_no);
@@ -2413,6 +2414,7 @@ static int NCR5380_abort(struct scsi_cmn
 			REMOVE(5, *prev, tmp, tmp->host_scribble);
 			(*prev) = (struct scsi_cmnd *) tmp->host_scribble;
 			tmp->host_scribble = NULL;
+			spin_unlock_irq(instance->host_lock);
 			tmp->result = DID_ABORT << 16;
 			dprintk(NDEBUG_ABORT, "scsi%d : abort removed command from issue queue.\n", instance->host_no);
 			tmp->scsi_done(tmp);
@@ -2436,6 +2438,7 @@ static int NCR5380_abort(struct scsi_cmn
  */
 
 	if (hostdata->connected) {
+		spin_unlock_irq(instance->host_lock);
 		dprintk(NDEBUG_ABORT, "scsi%d : abort failed, command connected.\n", instance->host_no);
 		return FAILED;
 	}
@@ -2468,8 +2471,10 @@ static int NCR5380_abort(struct scsi_cmn
 		if (cmd == tmp) {
 			dprintk(NDEBUG_ABORT, "scsi%d : aborting disconnected command.\n", instance->host_no);
 
-			if (NCR5380_select(instance, cmd))
+			if (NCR5380_select(instance, cmd)) {
+				spin_unlock_irq(instance->host_lock);
 				return FAILED;
+			}
 			dprintk(NDEBUG_ABORT, "scsi%d : nexus reestablished.\n", instance->host_no);
 
 			do_abort(instance);
@@ -2479,6 +2484,7 @@ static int NCR5380_abort(struct scsi_cmn
 					REMOVE(5, *prev, tmp, tmp->host_scribble);
 					*prev = (struct scsi_cmnd *) tmp->host_scribble;
 					tmp->host_scribble = NULL;
+					spin_unlock_irq(instance->host_lock);
 					tmp->result = DID_ABORT << 16;
 					tmp->scsi_done(tmp);
 					return SUCCESS;
@@ -2493,6 +2499,7 @@ static int NCR5380_abort(struct scsi_cmn
  * so we won't panic, but we will notify the user in case something really
  * broke.
  */
+	spin_unlock_irq(instance->host_lock);
 	printk(KERN_WARNING "scsi%d : warning : SCSI command probably completed successfully\n"
 			"         before abortion\n", instance->host_no);
 	return FAILED;



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

* [PATCH 27/71] ncr5380: Add missing lock in eh_abort_handler
@ 2015-11-18  8:35   ` Finn Thain
  0 siblings, 0 replies; 268+ messages in thread
From: Finn Thain @ 2015-11-18  8:35 UTC (permalink / raw)
  To: James E.J. Bottomley, Michael Schmitz, linux-m68k, linux-scsi,
	linux-kernel

[-- Attachment #1: ncr5380-spin_unlock-crash --]
[-- Type: text/plain, Size: 3488 bytes --]

The host spin lock needs to be acquired by NCR5380_abort() before it calls
NCR5380_select(). This patch doesn't actually fix the EH issues in this
driver but it does avoid this:

BUG: spinlock already unlocked on CPU#0, kworker/u4:1/14
 lock: 0xc0c0f834, .magic: dead4ead, .owner: <none>/-1, .owner_cpu: -1
 CPU: 0 PID: 14 Comm: kworker/u4:1 Not tainted 3.15.5 #5
 Workqueue: scsi_tmf_4 scmd_eh_abort_handler
 Call Trace:
 [ef885d70] [c0008acc] show_stack+0x70/0x1bc (unreliable)
 [ef885db0] [c0492a00] dump_stack+0x84/0x684
 [ef885dc0] [c006f314] spin_dump+0xd0/0xe8
 [ef885dd0] [c006f460] do_raw_spin_unlock+0xd4/0xd8
 [ef885df0] [c0491c8c] _raw_spin_unlock_irq+0x10/0x3c
 [ef885e00] [f381fe3c] NCR5380_select+0x3e4/0x6e8 [dmx3191d]
 [ef885e40] [f382026c] NCR5380_abort+0x12c/0x190 [dmx3191d]
 [ef885e60] [c02fec9c] scmd_eh_abort_handler+0x100/0x460
 [ef885e80] [c0046470] process_one_work+0x16c/0x420
 [ef885ea0] [c0046870] worker_thread+0x14c/0x430
 [ef885ed0] [c004e4f4] kthread+0xd8/0xec
 [ef885f40] [c00124d4] ret_from_kernel_thread+0x5c/0x64

Signed-off-by: Finn Thain <fthain@telegraphics.com.au>

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

Index: linux/drivers/scsi/NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/NCR5380.c	2015-11-18 19:33:39.000000000 +1100
+++ linux/drivers/scsi/NCR5380.c	2015-11-18 19:33:40.000000000 +1100
@@ -2367,6 +2367,7 @@ static int NCR5380_abort(struct scsi_cmn
 
 	scmd_printk(KERN_WARNING, cmd, "aborting command\n");
 
+	spin_lock_irq(instance->host_lock);
 	NCR5380_print_status(instance);
 
 	dprintk(NDEBUG_ABORT, "scsi%d : abort called\n", instance->host_no);
@@ -2413,6 +2414,7 @@ static int NCR5380_abort(struct scsi_cmn
 			REMOVE(5, *prev, tmp, tmp->host_scribble);
 			(*prev) = (struct scsi_cmnd *) tmp->host_scribble;
 			tmp->host_scribble = NULL;
+			spin_unlock_irq(instance->host_lock);
 			tmp->result = DID_ABORT << 16;
 			dprintk(NDEBUG_ABORT, "scsi%d : abort removed command from issue queue.\n", instance->host_no);
 			tmp->scsi_done(tmp);
@@ -2436,6 +2438,7 @@ static int NCR5380_abort(struct scsi_cmn
  */
 
 	if (hostdata->connected) {
+		spin_unlock_irq(instance->host_lock);
 		dprintk(NDEBUG_ABORT, "scsi%d : abort failed, command connected.\n", instance->host_no);
 		return FAILED;
 	}
@@ -2468,8 +2471,10 @@ static int NCR5380_abort(struct scsi_cmn
 		if (cmd == tmp) {
 			dprintk(NDEBUG_ABORT, "scsi%d : aborting disconnected command.\n", instance->host_no);
 
-			if (NCR5380_select(instance, cmd))
+			if (NCR5380_select(instance, cmd)) {
+				spin_unlock_irq(instance->host_lock);
 				return FAILED;
+			}
 			dprintk(NDEBUG_ABORT, "scsi%d : nexus reestablished.\n", instance->host_no);
 
 			do_abort(instance);
@@ -2479,6 +2484,7 @@ static int NCR5380_abort(struct scsi_cmn
 					REMOVE(5, *prev, tmp, tmp->host_scribble);
 					*prev = (struct scsi_cmnd *) tmp->host_scribble;
 					tmp->host_scribble = NULL;
+					spin_unlock_irq(instance->host_lock);
 					tmp->result = DID_ABORT << 16;
 					tmp->scsi_done(tmp);
 					return SUCCESS;
@@ -2493,6 +2499,7 @@ static int NCR5380_abort(struct scsi_cmn
  * so we won't panic, but we will notify the user in case something really
  * broke.
  */
+	spin_unlock_irq(instance->host_lock);
 	printk(KERN_WARNING "scsi%d : warning : SCSI command probably completed successfully\n"
 			"         before abortion\n", instance->host_no);
 	return FAILED;

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

* [PATCH 28/71] ncr5380: Drop DEF_SCSI_QCMD macro
  2015-11-18  8:34 ` Finn Thain
@ 2015-11-18  8:35   ` Finn Thain
  -1 siblings, 0 replies; 268+ messages in thread
From: Finn Thain @ 2015-11-18  8:35 UTC (permalink / raw)
  To: James E.J. Bottomley, Michael Schmitz, linux-m68k, linux-scsi,
	linux-kernel

[-- Attachment #1: ncr5380-drop-DEF_SCSI_QCMD --]
[-- Type: text/plain, Size: 3680 bytes --]

Remove the DEF_SCSI_QCMD macro (already removed from atari_NCR5380.c). The
lock provided by DEF_SCSI_QCMD is only needed for queue data structures.

Signed-off-by: Finn Thain <fthain@telegraphics.com.au>

---
 drivers/scsi/NCR5380.c       |   30 +++++++++++++++---------------
 drivers/scsi/atari_NCR5380.c |    2 +-
 2 files changed, 16 insertions(+), 16 deletions(-)

Index: linux/drivers/scsi/NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/NCR5380.c	2015-11-18 19:33:40.000000000 +1100
+++ linux/drivers/scsi/NCR5380.c	2015-11-18 19:33:41.000000000 +1100
@@ -801,22 +801,21 @@ static void NCR5380_exit(struct Scsi_Hos
 }
 
 /**
- *	NCR5380_queue_command 		-	queue a command
- *	@cmd: SCSI command
- *	@done: completion handler
+ * 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.
- *
- *	Locks: host lock taken by caller
+ * 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_lck(struct scsi_cmnd *cmd, void (*done) (struct scsi_cmnd *))
+static int NCR5380_queue_command(struct Scsi_Host *instance,
+                                 struct scsi_cmnd *cmd)
 {
-	struct Scsi_Host *instance = cmd->device->host;
-	struct NCR5380_hostdata *hostdata = (struct NCR5380_hostdata *) instance->hostdata;
+	struct NCR5380_hostdata *hostdata = shost_priv(instance);
 	struct scsi_cmnd *tmp;
+	unsigned long flags;
 
 #if (NDEBUG & NDEBUG_NO_WRITE)
 	switch (cmd->cmnd[0]) {
@@ -824,7 +823,7 @@ static int NCR5380_queue_command_lck(str
 	case WRITE_10:
 		printk("scsi%d : WRITE attempted with NO_WRITE debugging flag set\n", instance->host_no);
 		cmd->result = (DID_ERROR << 16);
-		done(cmd);
+		cmd->scsi_done(cmd);
 		return 0;
 	}
 #endif				/* (NDEBUG & NDEBUG_NO_WRITE) */
@@ -835,9 +834,10 @@ static int NCR5380_queue_command_lck(str
 	 */
 
 	cmd->host_scribble = NULL;
-	cmd->scsi_done = done;
 	cmd->result = 0;
 
+	spin_lock_irqsave(instance->host_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
@@ -854,6 +854,8 @@ static int NCR5380_queue_command_lck(str
 		LIST(cmd, tmp);
 		tmp->host_scribble = (unsigned char *) cmd;
 	}
+	spin_unlock_irqrestore(instance->host_lock, flags);
+
 	dprintk(NDEBUG_QUEUES, "scsi%d : command added to %s of queue\n", instance->host_no, (cmd->cmnd[0] == REQUEST_SENSE) ? "head" : "tail");
 
 	/* Run the coroutine if it isn't already running. */
@@ -862,8 +864,6 @@ static int NCR5380_queue_command_lck(str
 	return 0;
 }
 
-static DEF_SCSI_QCMD(NCR5380_queue_command)
-
 /**
  *	NCR5380_main	-	NCR state machines
  *
Index: linux/drivers/scsi/atari_NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/atari_NCR5380.c	2015-11-18 19:33:39.000000000 +1100
+++ linux/drivers/scsi/atari_NCR5380.c	2015-11-18 19:33:41.000000000 +1100
@@ -924,7 +924,7 @@ static void NCR5380_exit(struct Scsi_Hos
  * @instance: the relevant SCSI adapter
  * @cmd: SCSI command
  *
- * cmd is added to the per instance issue_queue, with minor
+ * 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.
  */



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

* [PATCH 28/71] ncr5380: Drop DEF_SCSI_QCMD macro
@ 2015-11-18  8:35   ` Finn Thain
  0 siblings, 0 replies; 268+ messages in thread
From: Finn Thain @ 2015-11-18  8:35 UTC (permalink / raw)
  To: James E.J. Bottomley, Michael Schmitz, linux-m68k, linux-scsi,
	linux-kernel

[-- Attachment #1: ncr5380-drop-DEF_SCSI_QCMD --]
[-- Type: text/plain, Size: 3678 bytes --]

Remove the DEF_SCSI_QCMD macro (already removed from atari_NCR5380.c). The
lock provided by DEF_SCSI_QCMD is only needed for queue data structures.

Signed-off-by: Finn Thain <fthain@telegraphics.com.au>

---
 drivers/scsi/NCR5380.c       |   30 +++++++++++++++---------------
 drivers/scsi/atari_NCR5380.c |    2 +-
 2 files changed, 16 insertions(+), 16 deletions(-)

Index: linux/drivers/scsi/NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/NCR5380.c	2015-11-18 19:33:40.000000000 +1100
+++ linux/drivers/scsi/NCR5380.c	2015-11-18 19:33:41.000000000 +1100
@@ -801,22 +801,21 @@ static void NCR5380_exit(struct Scsi_Hos
 }
 
 /**
- *	NCR5380_queue_command 		-	queue a command
- *	@cmd: SCSI command
- *	@done: completion handler
+ * 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.
- *
- *	Locks: host lock taken by caller
+ * 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_lck(struct scsi_cmnd *cmd, void (*done) (struct scsi_cmnd *))
+static int NCR5380_queue_command(struct Scsi_Host *instance,
+                                 struct scsi_cmnd *cmd)
 {
-	struct Scsi_Host *instance = cmd->device->host;
-	struct NCR5380_hostdata *hostdata = (struct NCR5380_hostdata *) instance->hostdata;
+	struct NCR5380_hostdata *hostdata = shost_priv(instance);
 	struct scsi_cmnd *tmp;
+	unsigned long flags;
 
 #if (NDEBUG & NDEBUG_NO_WRITE)
 	switch (cmd->cmnd[0]) {
@@ -824,7 +823,7 @@ static int NCR5380_queue_command_lck(str
 	case WRITE_10:
 		printk("scsi%d : WRITE attempted with NO_WRITE debugging flag set\n", instance->host_no);
 		cmd->result = (DID_ERROR << 16);
-		done(cmd);
+		cmd->scsi_done(cmd);
 		return 0;
 	}
 #endif				/* (NDEBUG & NDEBUG_NO_WRITE) */
@@ -835,9 +834,10 @@ static int NCR5380_queue_command_lck(str
 	 */
 
 	cmd->host_scribble = NULL;
-	cmd->scsi_done = done;
 	cmd->result = 0;
 
+	spin_lock_irqsave(instance->host_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
@@ -854,6 +854,8 @@ static int NCR5380_queue_command_lck(str
 		LIST(cmd, tmp);
 		tmp->host_scribble = (unsigned char *) cmd;
 	}
+	spin_unlock_irqrestore(instance->host_lock, flags);
+
 	dprintk(NDEBUG_QUEUES, "scsi%d : command added to %s of queue\n", instance->host_no, (cmd->cmnd[0] == REQUEST_SENSE) ? "head" : "tail");
 
 	/* Run the coroutine if it isn't already running. */
@@ -862,8 +864,6 @@ static int NCR5380_queue_command_lck(str
 	return 0;
 }
 
-static DEF_SCSI_QCMD(NCR5380_queue_command)
-
 /**
  *	NCR5380_main	-	NCR state machines
  *
Index: linux/drivers/scsi/atari_NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/atari_NCR5380.c	2015-11-18 19:33:39.000000000 +1100
+++ linux/drivers/scsi/atari_NCR5380.c	2015-11-18 19:33:41.000000000 +1100
@@ -924,7 +924,7 @@ static void NCR5380_exit(struct Scsi_Hos
  * @instance: the relevant SCSI adapter
  * @cmd: SCSI command
  *
- * cmd is added to the per instance issue_queue, with minor
+ * 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.
  */

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

* [PATCH 29/71] ncr5380: Remove references to linked commands
  2015-11-18  8:34 ` Finn Thain
@ 2015-11-18  8:35   ` Finn Thain
  -1 siblings, 0 replies; 268+ messages in thread
From: Finn Thain @ 2015-11-18  8:35 UTC (permalink / raw)
  To: James E.J. Bottomley, Michael Schmitz, linux-m68k, linux-scsi,
	linux-kernel

[-- Attachment #1: ncr5380-remove-LINKED --]
[-- Type: text/plain, Size: 6585 bytes --]

From: Hannes Reinecke <hare@suse.de>

Some old drivers partially implemented support for linked commands using
a "proposed" next_link pointer in struct scsi_cmnd that never actually
existed. Remove this code.

Signed-off-by: Finn Thain <fthain@telegraphics.com.au>

---

This is a modified version of Hannes' patch so I have dropped his
signed-off-by tag. This version has a rewritten commit log and also
removes additional references to linked commands from comments. This
version also omits the sun3_NCR5380.c changes since that file no
longer exists.

---
 drivers/scsi/NCR5380.c       |   42 ------------------------------
 drivers/scsi/atari_NCR5380.c |   60 -------------------------------------------
 2 files changed, 102 deletions(-)

Index: linux/drivers/scsi/NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/NCR5380.c	2015-11-18 19:33:41.000000000 +1100
+++ linux/drivers/scsi/NCR5380.c	2015-11-18 19:33:42.000000000 +1100
@@ -78,9 +78,6 @@
  * 
  * 4.  Test SCSI-II tagged queueing (I have no devices which support 
  *      tagged queueing)
- *
- * 5.  Test linked command handling code after Eric is ready with 
- *      the high level code.
  */
 #include <scsi/scsi_dbg.h>
 #include <scsi/scsi_transport_spi.h>
@@ -94,7 +91,6 @@
 #endif
 
 #ifndef notyet
-#undef LINKED
 #undef REAL_DMA
 #endif
 
@@ -191,8 +187,6 @@
  * DONT_USE_INTR - if defined, never use interrupts, even if we probe or
  *      override-configure an IRQ.
  *
- * LINKED - if defined, linked commands are supported.
- *
  * 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.
@@ -1916,42 +1910,6 @@ static void NCR5380_information_transfer
 				cmd->SCp.Message = tmp;
 
 				switch (tmp) {
-					/*
-					 * Linking lets us reduce the time required to get the 
-					 * next command out to the device, hopefully this will
-					 * mean we don't waste another revolution due to the delays
-					 * required by ARBITRATION and another SELECTION.
-					 *
-					 * In the current implementation proposal, low level drivers
-					 * merely have to start the next command, pointed to by 
-					 * next_link, done() is called as with unlinked commands.
-					 */
-#ifdef LINKED
-				case LINKED_CMD_COMPLETE:
-				case LINKED_FLG_CMD_COMPLETE:
-					/* Accept message by clearing ACK */
-					NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
-					dprintk(NDEBUG_LINKED, "scsi%d : target %d lun %llu linked command complete.\n", instance->host_no, cmd->device->id, cmd->device->lun);
-					/* 
-					 * Sanity check : A linked command should only terminate with
-					 * one of these messages if there are more linked commands
-					 * available.
-					 */
-					if (!cmd->next_link) {
-					    printk("scsi%d : target %d lun %llu linked command complete, no next_link\n" instance->host_no, cmd->device->id, cmd->device->lun);
-						sink = 1;
-						do_abort(instance);
-						return;
-					}
-					initialize_SCp(cmd->next_link);
-					/* The next command is still part of this process */
-					cmd->next_link->tag = cmd->tag;
-					cmd->result = cmd->SCp.Status | (cmd->SCp.Message << 8);
-					dprintk(NDEBUG_LINKED, "scsi%d : target %d lun %llu linked request done, calling scsi_done().\n", instance->host_no, cmd->device->id, cmd->device->lun);
-					cmd->scsi_done(cmd);
-					cmd = hostdata->connected;
-					break;
-#endif				/* def LINKED */
 				case ABORT:
 				case COMMAND_COMPLETE:
 					/* Accept message by clearing ACK */
Index: linux/drivers/scsi/atari_NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/atari_NCR5380.c	2015-11-18 19:33:41.000000000 +1100
+++ linux/drivers/scsi/atari_NCR5380.c	2015-11-18 19:33:42.000000000 +1100
@@ -66,12 +66,6 @@
  *
  */
 
-/*
- * Further development / testing that should be done :
- * 1.  Test linked command handling code after Eric is ready with
- *     the high level code.
- */
-
 /* Adapted for the sun3 by Sam Creasey. */
 
 #include <scsi/scsi_dbg.h>
@@ -98,10 +92,6 @@
 #define REMOVE(w,x,y,z)
 #endif
 
-#ifndef notyet
-#undef LINKED
-#endif
-
 /*
  * Design
  *
@@ -172,8 +162,6 @@
  * DIFFERENTIAL - if defined, NCR53c81 chips will use external differential
  *	transceivers.
  *
- * LINKED - if defined, linked commands are supported.
- *
  * 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
@@ -2210,54 +2198,6 @@ static void NCR5380_information_transfer
 				cmd->SCp.Message = tmp;
 
 				switch (tmp) {
-				/*
-				 * Linking lets us reduce the time required to get the
-				 * next command out to the device, hopefully this will
-				 * mean we don't waste another revolution due to the delays
-				 * required by ARBITRATION and another SELECTION.
-				 *
-				 * In the current implementation proposal, low level drivers
-				 * merely have to start the next command, pointed to by
-				 * next_link, done() is called as with unlinked commands.
-				 */
-#ifdef LINKED
-				case LINKED_CMD_COMPLETE:
-				case LINKED_FLG_CMD_COMPLETE:
-					/* Accept message by clearing ACK */
-					NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
-
-					dprintk(NDEBUG_LINKED, "scsi%d: target %d lun %llu linked command "
-						   "complete.\n", HOSTNO, cmd->device->id, cmd->device->lun);
-
-					/* Enable reselect interrupts */
-					NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
-					/*
-					 * Sanity check : A linked command should only terminate
-					 * with one of these messages if there are more linked
-					 * commands available.
-					 */
-
-					if (!cmd->next_link) {
-						 printk(KERN_NOTICE "scsi%d: target %d lun %llu "
-							"linked command complete, no next_link\n",
-							HOSTNO, cmd->device->id, cmd->device->lun);
-						sink = 1;
-						do_abort(instance);
-						return;
-					}
-
-					initialize_SCp(cmd->next_link);
-					/* The next command is still part of this process; copy it
-					 * and don't free it! */
-					cmd->next_link->tag = cmd->tag;
-					cmd->result = cmd->SCp.Status | (cmd->SCp.Message << 8);
-					dprintk(NDEBUG_LINKED, "scsi%d: target %d lun %llu linked request "
-						   "done, calling scsi_done().\n",
-						   HOSTNO, cmd->device->id, cmd->device->lun);
-					cmd->scsi_done(cmd);
-					cmd = hostdata->connected;
-					break;
-#endif /* def LINKED */
 				case ABORT:
 				case COMMAND_COMPLETE:
 					/* Accept message by clearing ACK */



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

* [PATCH 29/71] ncr5380: Remove references to linked commands
@ 2015-11-18  8:35   ` Finn Thain
  0 siblings, 0 replies; 268+ messages in thread
From: Finn Thain @ 2015-11-18  8:35 UTC (permalink / raw)
  To: James E.J. Bottomley, Michael Schmitz, linux-m68k, linux-scsi,
	linux-kernel

[-- Attachment #1: ncr5380-remove-LINKED --]
[-- Type: text/plain, Size: 6583 bytes --]

From: Hannes Reinecke <hare@suse.de>

Some old drivers partially implemented support for linked commands using
a "proposed" next_link pointer in struct scsi_cmnd that never actually
existed. Remove this code.

Signed-off-by: Finn Thain <fthain@telegraphics.com.au>

---

This is a modified version of Hannes' patch so I have dropped his
signed-off-by tag. This version has a rewritten commit log and also
removes additional references to linked commands from comments. This
version also omits the sun3_NCR5380.c changes since that file no
longer exists.

---
 drivers/scsi/NCR5380.c       |   42 ------------------------------
 drivers/scsi/atari_NCR5380.c |   60 -------------------------------------------
 2 files changed, 102 deletions(-)

Index: linux/drivers/scsi/NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/NCR5380.c	2015-11-18 19:33:41.000000000 +1100
+++ linux/drivers/scsi/NCR5380.c	2015-11-18 19:33:42.000000000 +1100
@@ -78,9 +78,6 @@
  * 
  * 4.  Test SCSI-II tagged queueing (I have no devices which support 
  *      tagged queueing)
- *
- * 5.  Test linked command handling code after Eric is ready with 
- *      the high level code.
  */
 #include <scsi/scsi_dbg.h>
 #include <scsi/scsi_transport_spi.h>
@@ -94,7 +91,6 @@
 #endif
 
 #ifndef notyet
-#undef LINKED
 #undef REAL_DMA
 #endif
 
@@ -191,8 +187,6 @@
  * DONT_USE_INTR - if defined, never use interrupts, even if we probe or
  *      override-configure an IRQ.
  *
- * LINKED - if defined, linked commands are supported.
- *
  * 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.
@@ -1916,42 +1910,6 @@ static void NCR5380_information_transfer
 				cmd->SCp.Message = tmp;
 
 				switch (tmp) {
-					/*
-					 * Linking lets us reduce the time required to get the 
-					 * next command out to the device, hopefully this will
-					 * mean we don't waste another revolution due to the delays
-					 * required by ARBITRATION and another SELECTION.
-					 *
-					 * In the current implementation proposal, low level drivers
-					 * merely have to start the next command, pointed to by 
-					 * next_link, done() is called as with unlinked commands.
-					 */
-#ifdef LINKED
-				case LINKED_CMD_COMPLETE:
-				case LINKED_FLG_CMD_COMPLETE:
-					/* Accept message by clearing ACK */
-					NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
-					dprintk(NDEBUG_LINKED, "scsi%d : target %d lun %llu linked command complete.\n", instance->host_no, cmd->device->id, cmd->device->lun);
-					/* 
-					 * Sanity check : A linked command should only terminate with
-					 * one of these messages if there are more linked commands
-					 * available.
-					 */
-					if (!cmd->next_link) {
-					    printk("scsi%d : target %d lun %llu linked command complete, no next_link\n" instance->host_no, cmd->device->id, cmd->device->lun);
-						sink = 1;
-						do_abort(instance);
-						return;
-					}
-					initialize_SCp(cmd->next_link);
-					/* The next command is still part of this process */
-					cmd->next_link->tag = cmd->tag;
-					cmd->result = cmd->SCp.Status | (cmd->SCp.Message << 8);
-					dprintk(NDEBUG_LINKED, "scsi%d : target %d lun %llu linked request done, calling scsi_done().\n", instance->host_no, cmd->device->id, cmd->device->lun);
-					cmd->scsi_done(cmd);
-					cmd = hostdata->connected;
-					break;
-#endif				/* def LINKED */
 				case ABORT:
 				case COMMAND_COMPLETE:
 					/* Accept message by clearing ACK */
Index: linux/drivers/scsi/atari_NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/atari_NCR5380.c	2015-11-18 19:33:41.000000000 +1100
+++ linux/drivers/scsi/atari_NCR5380.c	2015-11-18 19:33:42.000000000 +1100
@@ -66,12 +66,6 @@
  *
  */
 
-/*
- * Further development / testing that should be done :
- * 1.  Test linked command handling code after Eric is ready with
- *     the high level code.
- */
-
 /* Adapted for the sun3 by Sam Creasey. */
 
 #include <scsi/scsi_dbg.h>
@@ -98,10 +92,6 @@
 #define REMOVE(w,x,y,z)
 #endif
 
-#ifndef notyet
-#undef LINKED
-#endif
-
 /*
  * Design
  *
@@ -172,8 +162,6 @@
  * DIFFERENTIAL - if defined, NCR53c81 chips will use external differential
  *	transceivers.
  *
- * LINKED - if defined, linked commands are supported.
- *
  * 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
@@ -2210,54 +2198,6 @@ static void NCR5380_information_transfer
 				cmd->SCp.Message = tmp;
 
 				switch (tmp) {
-				/*
-				 * Linking lets us reduce the time required to get the
-				 * next command out to the device, hopefully this will
-				 * mean we don't waste another revolution due to the delays
-				 * required by ARBITRATION and another SELECTION.
-				 *
-				 * In the current implementation proposal, low level drivers
-				 * merely have to start the next command, pointed to by
-				 * next_link, done() is called as with unlinked commands.
-				 */
-#ifdef LINKED
-				case LINKED_CMD_COMPLETE:
-				case LINKED_FLG_CMD_COMPLETE:
-					/* Accept message by clearing ACK */
-					NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
-
-					dprintk(NDEBUG_LINKED, "scsi%d: target %d lun %llu linked command "
-						   "complete.\n", HOSTNO, cmd->device->id, cmd->device->lun);
-
-					/* Enable reselect interrupts */
-					NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
-					/*
-					 * Sanity check : A linked command should only terminate
-					 * with one of these messages if there are more linked
-					 * commands available.
-					 */
-
-					if (!cmd->next_link) {
-						 printk(KERN_NOTICE "scsi%d: target %d lun %llu "
-							"linked command complete, no next_link\n",
-							HOSTNO, cmd->device->id, cmd->device->lun);
-						sink = 1;
-						do_abort(instance);
-						return;
-					}
-
-					initialize_SCp(cmd->next_link);
-					/* The next command is still part of this process; copy it
-					 * and don't free it! */
-					cmd->next_link->tag = cmd->tag;
-					cmd->result = cmd->SCp.Status | (cmd->SCp.Message << 8);
-					dprintk(NDEBUG_LINKED, "scsi%d: target %d lun %llu linked request "
-						   "done, calling scsi_done().\n",
-						   HOSTNO, cmd->device->id, cmd->device->lun);
-					cmd->scsi_done(cmd);
-					cmd = hostdata->connected;
-					break;
-#endif /* def LINKED */
 				case ABORT:
 				case COMMAND_COMPLETE:
 					/* Accept message by clearing ACK */

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

* [PATCH 30/71] ncr5380: Add missing break after case MESSAGE_REJECT
  2015-11-18  8:34 ` Finn Thain
@ 2015-11-18  8:35   ` Finn Thain
  -1 siblings, 0 replies; 268+ messages in thread
From: Finn Thain @ 2015-11-18  8:35 UTC (permalink / raw)
  To: James E.J. Bottomley, Michael Schmitz, linux-m68k, linux-scsi,
	linux-kernel

[-- Attachment #1: ncr5380-missing-break --]
[-- Type: text/plain, Size: 829 bytes --]

MESSAGE REJECT does not imply DISCONNECT: the target is about to enter
MESSAGE IN or MESSAGE OUT phase.

This bug fix comes from atari_NCR5380.c. Unfortunately it never made it
into the original NCR5380.c core driver.

Signed-off-by: Finn Thain <fthain@telegraphics.com.au>

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

Index: linux/drivers/scsi/NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/NCR5380.c	2015-11-18 19:33:42.000000000 +1100
+++ linux/drivers/scsi/NCR5380.c	2015-11-18 19:33:43.000000000 +1100
@@ -1983,6 +1983,7 @@ static void NCR5380_information_transfer
 					default:
 						break;
 					}
+					break;
 				case DISCONNECT:{
 						/* Accept message by clearing ACK */
 						NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);



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

* [PATCH 30/71] ncr5380: Add missing break after case MESSAGE_REJECT
@ 2015-11-18  8:35   ` Finn Thain
  0 siblings, 0 replies; 268+ messages in thread
From: Finn Thain @ 2015-11-18  8:35 UTC (permalink / raw)
  To: James E.J. Bottomley, Michael Schmitz, linux-m68k, linux-scsi,
	linux-kernel

[-- Attachment #1: ncr5380-missing-break --]
[-- Type: text/plain, Size: 827 bytes --]

MESSAGE REJECT does not imply DISCONNECT: the target is about to enter
MESSAGE IN or MESSAGE OUT phase.

This bug fix comes from atari_NCR5380.c. Unfortunately it never made it
into the original NCR5380.c core driver.

Signed-off-by: Finn Thain <fthain@telegraphics.com.au>

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

Index: linux/drivers/scsi/NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/NCR5380.c	2015-11-18 19:33:42.000000000 +1100
+++ linux/drivers/scsi/NCR5380.c	2015-11-18 19:33:43.000000000 +1100
@@ -1983,6 +1983,7 @@ static void NCR5380_information_transfer
 					default:
 						break;
 					}
+					break;
 				case DISCONNECT:{
 						/* Accept message by clearing ACK */
 						NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);

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

* [PATCH 31/71] ncr5380: Fix !REQ timeout in do_abort()
  2015-11-18  8:34 ` Finn Thain
@ 2015-11-18  8:35   ` Finn Thain
  -1 siblings, 0 replies; 268+ messages in thread
From: Finn Thain @ 2015-11-18  8:35 UTC (permalink / raw)
  To: James E.J. Bottomley, Michael Schmitz, linux-m68k, linux-scsi,
	linux-kernel

[-- Attachment #1: ncr5380-do_abort-vs-poll_politely --]
[-- Type: text/plain, Size: 1865 bytes --]

NCR5380_poll_politely() never returns -1. That means do_abort() can fail
to handle a timeout after waiting for the target to negate REQ. Fix this
and cleanup other NCR5380_poll_politely() call sites.

Signed-off-by: Finn Thain <fthain@telegraphics.com.au>

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

Index: linux/drivers/scsi/NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/NCR5380.c	2015-11-18 19:33:43.000000000 +1100
+++ linux/drivers/scsi/NCR5380.c	2015-11-18 19:33:44.000000000 +1100
@@ -1264,7 +1264,7 @@ static int NCR5380_select(struct Scsi_Ho
 	err = NCR5380_poll_politely(instance, STATUS_REG, SR_REQ, SR_REQ, HZ);
 	spin_lock_irq(instance->host_lock);
 	
-	if(err) {
+	if (err < 0) {
 		printk(KERN_ERR "scsi%d: timeout at NCR5380.c:%d\n", instance->host_no, __LINE__);
 		NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
 		return -1;
@@ -1483,8 +1483,7 @@ static int do_abort(struct Scsi_Host *in
 	 */
 
 	rc = NCR5380_poll_politely(instance, STATUS_REG, SR_REQ, SR_REQ, 60 * HZ);
-	
-	if(rc < 0)
+	if (rc < 0)
 		return -1;
 
 	tmp = (unsigned char)rc;
@@ -1495,7 +1494,7 @@ static int do_abort(struct Scsi_Host *in
 		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);
 		NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_ATN);
-		if(rc == -1)
+		if (rc < 0)
 			return -1;
 	}
 	tmp = ABORT;
@@ -2192,7 +2191,8 @@ static void NCR5380_reselect(struct Scsi
 	 * FIXME: timeout needed and fail to work queeu
 	 */
 
-	if(NCR5380_poll_politely(instance, STATUS_REG, SR_REQ, SR_REQ, 2*HZ))
+	if (NCR5380_poll_politely(instance,
+	                          STATUS_REG, SR_REQ, SR_REQ, 2 * HZ) < 0)
 		abort = 1;
 
 	len = 1;



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

* [PATCH 31/71] ncr5380: Fix !REQ timeout in do_abort()
@ 2015-11-18  8:35   ` Finn Thain
  0 siblings, 0 replies; 268+ messages in thread
From: Finn Thain @ 2015-11-18  8:35 UTC (permalink / raw)
  To: James E.J. Bottomley, Michael Schmitz, linux-m68k, linux-scsi,
	linux-kernel

[-- Attachment #1: ncr5380-do_abort-vs-poll_politely --]
[-- Type: text/plain, Size: 1863 bytes --]

NCR5380_poll_politely() never returns -1. That means do_abort() can fail
to handle a timeout after waiting for the target to negate REQ. Fix this
and cleanup other NCR5380_poll_politely() call sites.

Signed-off-by: Finn Thain <fthain@telegraphics.com.au>

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

Index: linux/drivers/scsi/NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/NCR5380.c	2015-11-18 19:33:43.000000000 +1100
+++ linux/drivers/scsi/NCR5380.c	2015-11-18 19:33:44.000000000 +1100
@@ -1264,7 +1264,7 @@ static int NCR5380_select(struct Scsi_Ho
 	err = NCR5380_poll_politely(instance, STATUS_REG, SR_REQ, SR_REQ, HZ);
 	spin_lock_irq(instance->host_lock);
 	
-	if(err) {
+	if (err < 0) {
 		printk(KERN_ERR "scsi%d: timeout at NCR5380.c:%d\n", instance->host_no, __LINE__);
 		NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
 		return -1;
@@ -1483,8 +1483,7 @@ static int do_abort(struct Scsi_Host *in
 	 */
 
 	rc = NCR5380_poll_politely(instance, STATUS_REG, SR_REQ, SR_REQ, 60 * HZ);
-	
-	if(rc < 0)
+	if (rc < 0)
 		return -1;
 
 	tmp = (unsigned char)rc;
@@ -1495,7 +1494,7 @@ static int do_abort(struct Scsi_Host *in
 		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);
 		NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_ATN);
-		if(rc == -1)
+		if (rc < 0)
 			return -1;
 	}
 	tmp = ABORT;
@@ -2192,7 +2191,8 @@ static void NCR5380_reselect(struct Scsi
 	 * FIXME: timeout needed and fail to work queeu
 	 */
 
-	if(NCR5380_poll_politely(instance, STATUS_REG, SR_REQ, SR_REQ, 2*HZ))
+	if (NCR5380_poll_politely(instance,
+	                          STATUS_REG, SR_REQ, SR_REQ, 2 * HZ) < 0)
 		abort = 1;
 
 	len = 1;

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

* [PATCH 32/71] ncr5380: Fix bus phase in do_abort()
  2015-11-18  8:34 ` Finn Thain
@ 2015-11-18  8:35   ` Finn Thain
  -1 siblings, 0 replies; 268+ messages in thread
From: Finn Thain @ 2015-11-18  8:35 UTC (permalink / raw)
  To: James E.J. Bottomley, Michael Schmitz, linux-m68k, linux-scsi,
	linux-kernel

[-- Attachment #1: ncr5380-do_abort-vs-bus-phase --]
[-- Type: text/plain, Size: 1173 bytes --]

NCR5380_poll_politely() returns either 0 (success) or -ETIMEDOUT. However,
in do_abort(), the return value is incorrectly taken to be the status
register value. This means that the bus is put into DATA OUT phase instead
of MESSAGE OUT. Fix this.

Signed-off-by: Finn Thain <fthain@telegraphics.com.au>

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

Index: linux/drivers/scsi/NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/NCR5380.c	2015-11-18 19:33:44.000000000 +1100
+++ linux/drivers/scsi/NCR5380.c	2015-11-18 19:33:45.000000000 +1100
@@ -1486,11 +1486,11 @@ static int do_abort(struct Scsi_Host *in
 	if (rc < 0)
 		return -1;
 
-	tmp = (unsigned char)rc;
+	tmp = NCR5380_read(STATUS_REG) & PHASE_MASK;
 	
 	NCR5380_write(TARGET_COMMAND_REG, PHASE_SR_TO_TCR(tmp));
 
-	if ((tmp & PHASE_MASK) != PHASE_MSGOUT) {
+	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);
 		NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_ATN);



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

* [PATCH 32/71] ncr5380: Fix bus phase in do_abort()
@ 2015-11-18  8:35   ` Finn Thain
  0 siblings, 0 replies; 268+ messages in thread
From: Finn Thain @ 2015-11-18  8:35 UTC (permalink / raw)
  To: James E.J. Bottomley, Michael Schmitz, linux-m68k, linux-scsi,
	linux-kernel

[-- Attachment #1: ncr5380-do_abort-vs-bus-phase --]
[-- Type: text/plain, Size: 1171 bytes --]

NCR5380_poll_politely() returns either 0 (success) or -ETIMEDOUT. However,
in do_abort(), the return value is incorrectly taken to be the status
register value. This means that the bus is put into DATA OUT phase instead
of MESSAGE OUT. Fix this.

Signed-off-by: Finn Thain <fthain@telegraphics.com.au>

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

Index: linux/drivers/scsi/NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/NCR5380.c	2015-11-18 19:33:44.000000000 +1100
+++ linux/drivers/scsi/NCR5380.c	2015-11-18 19:33:45.000000000 +1100
@@ -1486,11 +1486,11 @@ static int do_abort(struct Scsi_Host *in
 	if (rc < 0)
 		return -1;
 
-	tmp = (unsigned char)rc;
+	tmp = NCR5380_read(STATUS_REG) & PHASE_MASK;
 	
 	NCR5380_write(TARGET_COMMAND_REG, PHASE_SR_TO_TCR(tmp));
 
-	if ((tmp & PHASE_MASK) != PHASE_MSGOUT) {
+	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);
 		NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_ATN);

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

* [PATCH 33/71] atari_NCR5380: Set do_abort() timeouts
  2015-11-18  8:34 ` Finn Thain
@ 2015-11-18  8:35   ` Finn Thain
  -1 siblings, 0 replies; 268+ messages in thread
From: Finn Thain @ 2015-11-18  8:35 UTC (permalink / raw)
  To: James E.J. Bottomley, Michael Schmitz, linux-m68k, linux-scsi,
	linux-kernel

[-- Attachment #1: atari_NCR5380-do_abort-timeouts --]
[-- Type: text/plain, Size: 4498 bytes --]

Use timeouts in do_abort() in atari_NCR5380.c instead of infinite loops.
Also fix the kernel-doc comment. Keep the two core driver forks in sync.

Signed-off-by: Finn Thain <fthain@telegraphics.com.au>

---
 drivers/scsi/NCR5380.c       |   26 +++++++++++++-------------
 drivers/scsi/atari_NCR5380.c |   34 +++++++++++++++++++++-------------
 2 files changed, 34 insertions(+), 26 deletions(-)

Index: linux/drivers/scsi/atari_NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/atari_NCR5380.c	2015-11-18 19:33:42.000000000 +1100
+++ linux/drivers/scsi/atari_NCR5380.c	2015-11-18 19:33:46.000000000 +1100
@@ -1829,19 +1829,19 @@ static void do_reset(struct Scsi_Host *i
 	local_irq_restore(flags);
 }
 
-/*
- * Function : do_abort (Scsi_Host *host)
+/**
+ * do_abort - abort the currently established nexus by going to
+ * MESSAGE OUT phase and sending an ABORT message.
+ * @instance: relevant scsi host instance
  *
- * Purpose : abort the currently established nexus.  Should only be
- *	called from a routine which can drop into a
- *
- * Returns : 0 on success, -1 on failure.
+ * Returns 0 on success, -1 on failure.
  */
 
 static int do_abort(struct Scsi_Host *instance)
 {
 	unsigned char tmp, *msgptr, phase;
 	int len;
+	int rc;
 
 	/* Request message out phase */
 	NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_ATN);
@@ -1856,16 +1856,20 @@ static int do_abort(struct Scsi_Host *in
 	 * the target sees, so we just handshake.
 	 */
 
-	while (!((tmp = NCR5380_read(STATUS_REG)) & SR_REQ))
-		;
+	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_MASK) != PHASE_MSGOUT) {
-		NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_ATN |
-			      ICR_ASSERT_ACK);
-		while (NCR5380_read(STATUS_REG) & SR_REQ)
-			;
+	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);
 	}
 
@@ -1881,6 +1885,10 @@ static int do_abort(struct Scsi_Host *in
 	 */
 
 	return len ? -1 : 0;
+
+timeout:
+	NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
+	return -1;
 }
 
 #if defined(REAL_DMA)
Index: linux/drivers/scsi/NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/NCR5380.c	2015-11-18 19:33:45.000000000 +1100
+++ linux/drivers/scsi/NCR5380.c	2015-11-18 19:33:46.000000000 +1100
@@ -1451,16 +1451,12 @@ static void do_reset(struct Scsi_Host *i
 	local_irq_restore(flags);
 }
 
-/*
- * Function : do_abort (Scsi_Host *host)
- * 
- * Purpose : abort the currently established nexus.  Should only be 
- *      called from a routine which can drop into a 
- * 
- * Returns : 0 on success, -1 on failure.
+/**
+ * do_abort - abort the currently established nexus by going to
+ * MESSAGE OUT phase and sending an ABORT message.
+ * @instance: relevant scsi host instance
  *
- * Locks: queue lock held by caller
- *	FIXME: sort this out and get new_eh running
+ * Returns 0 on success, -1 on failure.
  */
 
 static int do_abort(struct Scsi_Host *instance)
@@ -1482,9 +1478,9 @@ static int do_abort(struct Scsi_Host *in
 	 * the target sees, so we just handshake.
 	 */
 
-	rc = NCR5380_poll_politely(instance, STATUS_REG, SR_REQ, SR_REQ, 60 * HZ);
+	rc = NCR5380_poll_politely(instance, STATUS_REG, SR_REQ, SR_REQ, 10 * HZ);
 	if (rc < 0)
-		return -1;
+		goto timeout;
 
 	tmp = NCR5380_read(STATUS_REG) & PHASE_MASK;
 	
@@ -1493,9 +1489,9 @@ static int do_abort(struct Scsi_Host *in
 	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);
-		NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_ATN);
 		if (rc < 0)
-			return -1;
+			goto timeout;
+		NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_ATN);
 	}
 	tmp = ABORT;
 	msgptr = &tmp;
@@ -1509,6 +1505,10 @@ static int do_abort(struct Scsi_Host *in
 	 */
 
 	return len ? -1 : 0;
+
+timeout:
+	NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
+	return -1;
 }
 
 #if defined(REAL_DMA) || defined(PSEUDO_DMA) || defined (REAL_DMA_POLL)



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

* [PATCH 33/71] atari_NCR5380: Set do_abort() timeouts
@ 2015-11-18  8:35   ` Finn Thain
  0 siblings, 0 replies; 268+ messages in thread
From: Finn Thain @ 2015-11-18  8:35 UTC (permalink / raw)
  To: James E.J. Bottomley, Michael Schmitz, linux-m68k, linux-scsi,
	linux-kernel

[-- Attachment #1: atari_NCR5380-do_abort-timeouts --]
[-- Type: text/plain, Size: 4496 bytes --]

Use timeouts in do_abort() in atari_NCR5380.c instead of infinite loops.
Also fix the kernel-doc comment. Keep the two core driver forks in sync.

Signed-off-by: Finn Thain <fthain@telegraphics.com.au>

---
 drivers/scsi/NCR5380.c       |   26 +++++++++++++-------------
 drivers/scsi/atari_NCR5380.c |   34 +++++++++++++++++++++-------------
 2 files changed, 34 insertions(+), 26 deletions(-)

Index: linux/drivers/scsi/atari_NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/atari_NCR5380.c	2015-11-18 19:33:42.000000000 +1100
+++ linux/drivers/scsi/atari_NCR5380.c	2015-11-18 19:33:46.000000000 +1100
@@ -1829,19 +1829,19 @@ static void do_reset(struct Scsi_Host *i
 	local_irq_restore(flags);
 }
 
-/*
- * Function : do_abort (Scsi_Host *host)
+/**
+ * do_abort - abort the currently established nexus by going to
+ * MESSAGE OUT phase and sending an ABORT message.
+ * @instance: relevant scsi host instance
  *
- * Purpose : abort the currently established nexus.  Should only be
- *	called from a routine which can drop into a
- *
- * Returns : 0 on success, -1 on failure.
+ * Returns 0 on success, -1 on failure.
  */
 
 static int do_abort(struct Scsi_Host *instance)
 {
 	unsigned char tmp, *msgptr, phase;
 	int len;
+	int rc;
 
 	/* Request message out phase */
 	NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_ATN);
@@ -1856,16 +1856,20 @@ static int do_abort(struct Scsi_Host *in
 	 * the target sees, so we just handshake.
 	 */
 
-	while (!((tmp = NCR5380_read(STATUS_REG)) & SR_REQ))
-		;
+	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_MASK) != PHASE_MSGOUT) {
-		NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_ATN |
-			      ICR_ASSERT_ACK);
-		while (NCR5380_read(STATUS_REG) & SR_REQ)
-			;
+	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);
 	}
 
@@ -1881,6 +1885,10 @@ static int do_abort(struct Scsi_Host *in
 	 */
 
 	return len ? -1 : 0;
+
+timeout:
+	NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
+	return -1;
 }
 
 #if defined(REAL_DMA)
Index: linux/drivers/scsi/NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/NCR5380.c	2015-11-18 19:33:45.000000000 +1100
+++ linux/drivers/scsi/NCR5380.c	2015-11-18 19:33:46.000000000 +1100
@@ -1451,16 +1451,12 @@ static void do_reset(struct Scsi_Host *i
 	local_irq_restore(flags);
 }
 
-/*
- * Function : do_abort (Scsi_Host *host)
- * 
- * Purpose : abort the currently established nexus.  Should only be 
- *      called from a routine which can drop into a 
- * 
- * Returns : 0 on success, -1 on failure.
+/**
+ * do_abort - abort the currently established nexus by going to
+ * MESSAGE OUT phase and sending an ABORT message.
+ * @instance: relevant scsi host instance
  *
- * Locks: queue lock held by caller
- *	FIXME: sort this out and get new_eh running
+ * Returns 0 on success, -1 on failure.
  */
 
 static int do_abort(struct Scsi_Host *instance)
@@ -1482,9 +1478,9 @@ static int do_abort(struct Scsi_Host *in
 	 * the target sees, so we just handshake.
 	 */
 
-	rc = NCR5380_poll_politely(instance, STATUS_REG, SR_REQ, SR_REQ, 60 * HZ);
+	rc = NCR5380_poll_politely(instance, STATUS_REG, SR_REQ, SR_REQ, 10 * HZ);
 	if (rc < 0)
-		return -1;
+		goto timeout;
 
 	tmp = NCR5380_read(STATUS_REG) & PHASE_MASK;
 	
@@ -1493,9 +1489,9 @@ static int do_abort(struct Scsi_Host *in
 	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);
-		NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_ATN);
 		if (rc < 0)
-			return -1;
+			goto timeout;
+		NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_ATN);
 	}
 	tmp = ABORT;
 	msgptr = &tmp;
@@ -1509,6 +1505,10 @@ static int do_abort(struct Scsi_Host *in
 	 */
 
 	return len ? -1 : 0;
+
+timeout:
+	NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
+	return -1;
 }
 
 #if defined(REAL_DMA) || defined(PSEUDO_DMA) || defined (REAL_DMA_POLL)

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

* [PATCH 34/71] atari_NCR5380: Use arbitration timeout
  2015-11-18  8:34 ` Finn Thain
@ 2015-11-18  8:35   ` Finn Thain
  -1 siblings, 0 replies; 268+ messages in thread
From: Finn Thain @ 2015-11-18  8:35 UTC (permalink / raw)
  To: James E.J. Bottomley, Michael Schmitz, linux-m68k, linux-scsi,
	linux-kernel

[-- Attachment #1: atari_NCR5380-use-arbitration-timeout --]
[-- Type: text/plain, Size: 6128 bytes --]

Allow target selection to fail with a timeout instead of waiting in
infinite loops. This gets rid of the unused NCR_TIMEOUT macro, it is more
defensive and has proved helpful in debugging.

Signed-off-by: Finn Thain <fthain@telegraphics.com.au>

---
 drivers/scsi/NCR5380.c       |   44 ++++++++++++++++++---------------
 drivers/scsi/atari_NCR5380.c |   57 ++++++++++++++++++-------------------------
 2 files changed, 49 insertions(+), 52 deletions(-)

Index: linux/drivers/scsi/atari_NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/atari_NCR5380.c	2015-11-18 19:33:46.000000000 +1100
+++ linux/drivers/scsi/atari_NCR5380.c	2015-11-18 19:33:47.000000000 +1100
@@ -1406,6 +1406,7 @@ static int NCR5380_select(struct Scsi_Ho
 	int len;
 	int err;
 	unsigned long flags;
+	unsigned long timeout;
 
 	NCR5380_dprint(NDEBUG_ARBITRATION, instance);
 	dprintk(NDEBUG_ARBITRATION, "scsi%d: starting arbitration, id = %d\n", HOSTNO,
@@ -1430,42 +1431,28 @@ static int NCR5380_select(struct Scsi_Ho
 	NCR5380_write(OUTPUT_DATA_REG, hostdata->id_mask);
 	NCR5380_write(MODE_REG, MR_ARBITRATE);
 
-	local_irq_restore(flags);
+	/* The chip now waits for BUS FREE phase. Then after the 800 ns
+	 * Bus Free Delay, arbitration will begin.
+	 */
 
-	/* Wait for arbitration logic to complete */
-#if defined(NCR_TIMEOUT)
-	{
-		unsigned long timeout = jiffies + 2*NCR_TIMEOUT;
-
-		while (!(NCR5380_read(INITIATOR_COMMAND_REG) & ICR_ARBITRATION_PROGRESS) &&
-		       time_before(jiffies, timeout) && !hostdata->connected)
-			;
-		if (time_after_eq(jiffies, timeout)) {
-			printk("scsi : arbitration timeout at %d\n", __LINE__);
+	local_irq_restore(flags);
+	timeout = jiffies + HZ;
+	while (1) {
+		if (time_is_before_jiffies(timeout)) {
 			NCR5380_write(MODE_REG, MR_BASE);
-			NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
+			shost_printk(KERN_ERR, instance,
+			             "select: arbitration timeout\n");
 			return -1;
 		}
+		if (!(NCR5380_read(MODE_REG) & MR_ARBITRATE)) {
+			/* Reselection interrupt */
+			return -1;
+		}
+		if (NCR5380_read(INITIATOR_COMMAND_REG) & ICR_ARBITRATION_PROGRESS)
+			break;
 	}
-#else /* NCR_TIMEOUT */
-	while (!(NCR5380_read(INITIATOR_COMMAND_REG) & ICR_ARBITRATION_PROGRESS) &&
-	       !hostdata->connected)
-		;
-#endif
-
-	dprintk(NDEBUG_ARBITRATION, "scsi%d: arbitration complete\n", HOSTNO);
-
-	if (hostdata->connected) {
-		NCR5380_write(MODE_REG, MR_BASE);
-		return -1;
-	}
-	/*
-	 * The arbitration delay is 2.2us, but this is a minimum and there is
-	 * no maximum so we can safely sleep for ceil(2.2) usecs to accommodate
-	 * the integral nature of udelay().
-	 *
-	 */
 
+	/* The SCSI-2 arbitration delay is 2.4 us */
 	udelay(3);
 
 	/* Check for lost arbitration */
@@ -1628,8 +1615,14 @@ static int NCR5380_select(struct Scsi_Ho
 	 */
 
 	/* Wait for start of REQ/ACK handshake */
-	while (!(NCR5380_read(STATUS_REG) & SR_REQ))
-		;
+
+	err = NCR5380_poll_politely(instance, STATUS_REG, SR_REQ, SR_REQ, HZ);
+	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);
+		return -1;
+	}
 
 	dprintk(NDEBUG_SELECTION, "scsi%d: target %d selected, going into MESSAGE OUT phase.\n",
 		   HOSTNO, cmd->device->id);
Index: linux/drivers/scsi/NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/NCR5380.c	2015-11-18 19:33:46.000000000 +1100
+++ linux/drivers/scsi/NCR5380.c	2015-11-18 19:33:47.000000000 +1100
@@ -1076,6 +1076,7 @@ static int NCR5380_select(struct Scsi_Ho
 	unsigned char *data;
 	int len;
 	int err;
+	unsigned long timeout;
 
 	NCR5380_dprint(NDEBUG_ARBITRATION, instance);
 	dprintk(NDEBUG_ARBITRATION, "scsi%d : starting arbitration, id = %d\n", instance->host_no, instance->this_id);
@@ -1094,28 +1095,31 @@ static int NCR5380_select(struct Scsi_Ho
 	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.
+	 */
 
-	/* We can be relaxed here, interrupts are on, we are
-	   in workqueue context, the birds are singing in the trees */
 	spin_unlock_irq(instance->host_lock);
-	err = NCR5380_poll_politely(instance, INITIATOR_COMMAND_REG, ICR_ARBITRATION_PROGRESS, ICR_ARBITRATION_PROGRESS, 5*HZ);
-	spin_lock_irq(instance->host_lock);
-	if (err < 0) {
-		printk(KERN_DEBUG "scsi: arbitration timeout at %d\n", __LINE__);
-		NCR5380_write(MODE_REG, MR_BASE);
-		NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
-		return -1;
+	timeout = jiffies + HZ;
+	while (1) {
+		if (time_is_before_jiffies(timeout)) {
+			NCR5380_write(MODE_REG, MR_BASE);
+			shost_printk(KERN_ERR, instance,
+			             "select: arbitration timeout\n");
+			spin_lock_irq(instance->host_lock);
+			return -1;
+		}
+		spin_lock_irq(instance->host_lock);
+		if (!(NCR5380_read(MODE_REG) & MR_ARBITRATE)) {
+			/* Reselection interrupt */
+			return -1;
+		}
+		if (NCR5380_read(INITIATOR_COMMAND_REG) & ICR_ARBITRATION_PROGRESS)
+			break;
+		spin_unlock_irq(instance->host_lock);
 	}
 
-	dprintk(NDEBUG_ARBITRATION, "scsi%d : arbitration complete\n", instance->host_no);
-
-	/* 
-	 * The arbitration delay is 2.2us, but this is a minimum and there is 
-	 * no maximum so we can safely sleep for ceil(2.2) usecs to accommodate
-	 * the integral nature of udelay().
-	 *
-	 */
-
+	/* The SCSI-2 arbitration delay is 2.4 us */
 	udelay(3);
 
 	/* Check for lost arbitration */
@@ -1263,9 +1267,9 @@ static int NCR5380_select(struct Scsi_Ho
 	spin_unlock_irq(instance->host_lock);
 	err = NCR5380_poll_politely(instance, STATUS_REG, SR_REQ, SR_REQ, HZ);
 	spin_lock_irq(instance->host_lock);
-	
 	if (err < 0) {
-		printk(KERN_ERR "scsi%d: timeout at NCR5380.c:%d\n", instance->host_no, __LINE__);
+		shost_printk(KERN_ERR, instance, "select: REQ timeout\n");
+		NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
 		NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
 		return -1;
 	}



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

* [PATCH 34/71] atari_NCR5380: Use arbitration timeout
@ 2015-11-18  8:35   ` Finn Thain
  0 siblings, 0 replies; 268+ messages in thread
From: Finn Thain @ 2015-11-18  8:35 UTC (permalink / raw)
  To: James E.J. Bottomley, Michael Schmitz, linux-m68k, linux-scsi,
	linux-kernel

[-- Attachment #1: atari_NCR5380-use-arbitration-timeout --]
[-- Type: text/plain, Size: 6126 bytes --]

Allow target selection to fail with a timeout instead of waiting in
infinite loops. This gets rid of the unused NCR_TIMEOUT macro, it is more
defensive and has proved helpful in debugging.

Signed-off-by: Finn Thain <fthain@telegraphics.com.au>

---
 drivers/scsi/NCR5380.c       |   44 ++++++++++++++++++---------------
 drivers/scsi/atari_NCR5380.c |   57 ++++++++++++++++++-------------------------
 2 files changed, 49 insertions(+), 52 deletions(-)

Index: linux/drivers/scsi/atari_NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/atari_NCR5380.c	2015-11-18 19:33:46.000000000 +1100
+++ linux/drivers/scsi/atari_NCR5380.c	2015-11-18 19:33:47.000000000 +1100
@@ -1406,6 +1406,7 @@ static int NCR5380_select(struct Scsi_Ho
 	int len;
 	int err;
 	unsigned long flags;
+	unsigned long timeout;
 
 	NCR5380_dprint(NDEBUG_ARBITRATION, instance);
 	dprintk(NDEBUG_ARBITRATION, "scsi%d: starting arbitration, id = %d\n", HOSTNO,
@@ -1430,42 +1431,28 @@ static int NCR5380_select(struct Scsi_Ho
 	NCR5380_write(OUTPUT_DATA_REG, hostdata->id_mask);
 	NCR5380_write(MODE_REG, MR_ARBITRATE);
 
-	local_irq_restore(flags);
+	/* The chip now waits for BUS FREE phase. Then after the 800 ns
+	 * Bus Free Delay, arbitration will begin.
+	 */
 
-	/* Wait for arbitration logic to complete */
-#if defined(NCR_TIMEOUT)
-	{
-		unsigned long timeout = jiffies + 2*NCR_TIMEOUT;
-
-		while (!(NCR5380_read(INITIATOR_COMMAND_REG) & ICR_ARBITRATION_PROGRESS) &&
-		       time_before(jiffies, timeout) && !hostdata->connected)
-			;
-		if (time_after_eq(jiffies, timeout)) {
-			printk("scsi : arbitration timeout at %d\n", __LINE__);
+	local_irq_restore(flags);
+	timeout = jiffies + HZ;
+	while (1) {
+		if (time_is_before_jiffies(timeout)) {
 			NCR5380_write(MODE_REG, MR_BASE);
-			NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
+			shost_printk(KERN_ERR, instance,
+			             "select: arbitration timeout\n");
 			return -1;
 		}
+		if (!(NCR5380_read(MODE_REG) & MR_ARBITRATE)) {
+			/* Reselection interrupt */
+			return -1;
+		}
+		if (NCR5380_read(INITIATOR_COMMAND_REG) & ICR_ARBITRATION_PROGRESS)
+			break;
 	}
-#else /* NCR_TIMEOUT */
-	while (!(NCR5380_read(INITIATOR_COMMAND_REG) & ICR_ARBITRATION_PROGRESS) &&
-	       !hostdata->connected)
-		;
-#endif
-
-	dprintk(NDEBUG_ARBITRATION, "scsi%d: arbitration complete\n", HOSTNO);
-
-	if (hostdata->connected) {
-		NCR5380_write(MODE_REG, MR_BASE);
-		return -1;
-	}
-	/*
-	 * The arbitration delay is 2.2us, but this is a minimum and there is
-	 * no maximum so we can safely sleep for ceil(2.2) usecs to accommodate
-	 * the integral nature of udelay().
-	 *
-	 */
 
+	/* The SCSI-2 arbitration delay is 2.4 us */
 	udelay(3);
 
 	/* Check for lost arbitration */
@@ -1628,8 +1615,14 @@ static int NCR5380_select(struct Scsi_Ho
 	 */
 
 	/* Wait for start of REQ/ACK handshake */
-	while (!(NCR5380_read(STATUS_REG) & SR_REQ))
-		;
+
+	err = NCR5380_poll_politely(instance, STATUS_REG, SR_REQ, SR_REQ, HZ);
+	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);
+		return -1;
+	}
 
 	dprintk(NDEBUG_SELECTION, "scsi%d: target %d selected, going into MESSAGE OUT phase.\n",
 		   HOSTNO, cmd->device->id);
Index: linux/drivers/scsi/NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/NCR5380.c	2015-11-18 19:33:46.000000000 +1100
+++ linux/drivers/scsi/NCR5380.c	2015-11-18 19:33:47.000000000 +1100
@@ -1076,6 +1076,7 @@ static int NCR5380_select(struct Scsi_Ho
 	unsigned char *data;
 	int len;
 	int err;
+	unsigned long timeout;
 
 	NCR5380_dprint(NDEBUG_ARBITRATION, instance);
 	dprintk(NDEBUG_ARBITRATION, "scsi%d : starting arbitration, id = %d\n", instance->host_no, instance->this_id);
@@ -1094,28 +1095,31 @@ static int NCR5380_select(struct Scsi_Ho
 	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.
+	 */
 
-	/* We can be relaxed here, interrupts are on, we are
-	   in workqueue context, the birds are singing in the trees */
 	spin_unlock_irq(instance->host_lock);
-	err = NCR5380_poll_politely(instance, INITIATOR_COMMAND_REG, ICR_ARBITRATION_PROGRESS, ICR_ARBITRATION_PROGRESS, 5*HZ);
-	spin_lock_irq(instance->host_lock);
-	if (err < 0) {
-		printk(KERN_DEBUG "scsi: arbitration timeout at %d\n", __LINE__);
-		NCR5380_write(MODE_REG, MR_BASE);
-		NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
-		return -1;
+	timeout = jiffies + HZ;
+	while (1) {
+		if (time_is_before_jiffies(timeout)) {
+			NCR5380_write(MODE_REG, MR_BASE);
+			shost_printk(KERN_ERR, instance,
+			             "select: arbitration timeout\n");
+			spin_lock_irq(instance->host_lock);
+			return -1;
+		}
+		spin_lock_irq(instance->host_lock);
+		if (!(NCR5380_read(MODE_REG) & MR_ARBITRATE)) {
+			/* Reselection interrupt */
+			return -1;
+		}
+		if (NCR5380_read(INITIATOR_COMMAND_REG) & ICR_ARBITRATION_PROGRESS)
+			break;
+		spin_unlock_irq(instance->host_lock);
 	}
 
-	dprintk(NDEBUG_ARBITRATION, "scsi%d : arbitration complete\n", instance->host_no);
-
-	/* 
-	 * The arbitration delay is 2.2us, but this is a minimum and there is 
-	 * no maximum so we can safely sleep for ceil(2.2) usecs to accommodate
-	 * the integral nature of udelay().
-	 *
-	 */
-
+	/* The SCSI-2 arbitration delay is 2.4 us */
 	udelay(3);
 
 	/* Check for lost arbitration */
@@ -1263,9 +1267,9 @@ static int NCR5380_select(struct Scsi_Ho
 	spin_unlock_irq(instance->host_lock);
 	err = NCR5380_poll_politely(instance, STATUS_REG, SR_REQ, SR_REQ, HZ);
 	spin_lock_irq(instance->host_lock);
-	
 	if (err < 0) {
-		printk(KERN_ERR "scsi%d: timeout at NCR5380.c:%d\n", instance->host_no, __LINE__);
+		shost_printk(KERN_ERR, instance, "select: REQ timeout\n");
+		NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
 		NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
 		return -1;
 	}

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

* [PATCH 35/71] ncr5380: Dont wait for BUS FREE after disconnect
  2015-11-18  8:34 ` Finn Thain
@ 2015-11-18  8:35   ` Finn Thain
  -1 siblings, 0 replies; 268+ messages in thread
From: Finn Thain @ 2015-11-18  8:35 UTC (permalink / raw)
  To: James E.J. Bottomley, Michael Schmitz, linux-m68k, linux-scsi,
	linux-kernel

[-- Attachment #1: ncr5380-dont-wait-for-bus-free --]
[-- Type: text/plain, Size: 3573 bytes --]

When there is a queued command and no connected command, NCR5380_select()
is called and arbitration begins. The chip waits for BUS FREE once the
MR_ARBITRATE bit in the mode register is enabled. That means there is
no need to wait for BUS FREE after disconnecting.

There is presently no polling for BUS FREE after sending an ABORT or
other message that might lead to disconnection. It only happens after
COMMAND COMPLETE or DISCONNECT messages, which seems inconsistent.
Remove the polling for !BSY in the COMMAND COMPLETE and DISCONNECT
cases.

BTW, the comments say "avoid nasty timeouts" and perhaps BUS FREE polling
was somehow helpful back in Linux v0.99.14u, when it was introduced.
The relevant timeout is presently 1 second (for bus arbitration).

Signed-off-by: Finn Thain <fthain@telegraphics.com.au>

---
 drivers/scsi/NCR5380.c       |    7 -------
 drivers/scsi/atari_NCR5380.c |   11 -----------
 2 files changed, 18 deletions(-)

Index: linux/drivers/scsi/NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/NCR5380.c	2015-11-18 19:33:47.000000000 +1100
+++ linux/drivers/scsi/NCR5380.c	2015-11-18 19:33:48.000000000 +1100
@@ -1969,9 +1969,6 @@ static void NCR5380_information_transfer
 					 * arbitration can resume.
 					 */
 					NCR5380_write(TARGET_COMMAND_REG, 0);
-
-					while ((NCR5380_read(STATUS_REG) & SR_BSY) && !hostdata->connected)
-						barrier();
 					return;
 				case MESSAGE_REJECT:
 					/* Accept message by clearing ACK */
@@ -2004,10 +2001,6 @@ static void NCR5380_information_transfer
 
 						/* Enable reselect interrupts */
 						NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
-						/* Wait for bus free to avoid nasty timeouts - FIXME timeout !*/
-						/* NCR538_poll_politely(instance, STATUS_REG, SR_BSY, 0, 30 * HZ); */
-						while ((NCR5380_read(STATUS_REG) & SR_BSY) && !hostdata->connected)
-							barrier();
 						return;
 					}
 					/* 
Index: linux/drivers/scsi/atari_NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/atari_NCR5380.c	2015-11-18 19:33:47.000000000 +1100
+++ linux/drivers/scsi/atari_NCR5380.c	2015-11-18 19:33:48.000000000 +1100
@@ -2207,7 +2207,6 @@ static void NCR5380_information_transfer
 						  "completed\n", HOSTNO, cmd->device->id, cmd->device->lun);
 
 					local_irq_save(flags);
-					hostdata->retain_dma_intr++;
 					hostdata->connected = NULL;
 #ifdef SUPPORT_TAGS
 					cmd_free_tag(cmd);
@@ -2276,8 +2275,6 @@ static void NCR5380_information_transfer
 						cmd->scsi_done(cmd);
 					}
 
-					local_irq_restore(flags);
-
 					NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
 					/*
 					 * Restore phase bits to 0 so an interrupted selection,
@@ -2285,11 +2282,6 @@ static void NCR5380_information_transfer
 					 */
 					NCR5380_write(TARGET_COMMAND_REG, 0);
 
-					while ((NCR5380_read(STATUS_REG) & SR_BSY) && !hostdata->connected)
-						barrier();
-
-					local_irq_save(flags);
-					hostdata->retain_dma_intr--;
 					/* ++roman: For Falcon SCSI, release the lock on the
 					 * ST-DMA here if no other commands are waiting on the
 					 * disconnected queue.
@@ -2343,9 +2335,6 @@ static void NCR5380_information_transfer
 
 					/* Enable reselect interrupts */
 					NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
-					/* Wait for bus free to avoid nasty timeouts */
-					while ((NCR5380_read(STATUS_REG) & SR_BSY) && !hostdata->connected)
-						barrier();
 #ifdef SUN3_SCSI_VME
 					dregs->csr |= CSR_DMA_ENABLE;
 #endif



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

* [PATCH 35/71] ncr5380: Dont wait for BUS FREE after disconnect
@ 2015-11-18  8:35   ` Finn Thain
  0 siblings, 0 replies; 268+ messages in thread
From: Finn Thain @ 2015-11-18  8:35 UTC (permalink / raw)
  To: James E.J. Bottomley, Michael Schmitz, linux-m68k, linux-scsi,
	linux-kernel

[-- Attachment #1: ncr5380-dont-wait-for-bus-free --]
[-- Type: text/plain, Size: 3571 bytes --]

When there is a queued command and no connected command, NCR5380_select()
is called and arbitration begins. The chip waits for BUS FREE once the
MR_ARBITRATE bit in the mode register is enabled. That means there is
no need to wait for BUS FREE after disconnecting.

There is presently no polling for BUS FREE after sending an ABORT or
other message that might lead to disconnection. It only happens after
COMMAND COMPLETE or DISCONNECT messages, which seems inconsistent.
Remove the polling for !BSY in the COMMAND COMPLETE and DISCONNECT
cases.

BTW, the comments say "avoid nasty timeouts" and perhaps BUS FREE polling
was somehow helpful back in Linux v0.99.14u, when it was introduced.
The relevant timeout is presently 1 second (for bus arbitration).

Signed-off-by: Finn Thain <fthain@telegraphics.com.au>

---
 drivers/scsi/NCR5380.c       |    7 -------
 drivers/scsi/atari_NCR5380.c |   11 -----------
 2 files changed, 18 deletions(-)

Index: linux/drivers/scsi/NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/NCR5380.c	2015-11-18 19:33:47.000000000 +1100
+++ linux/drivers/scsi/NCR5380.c	2015-11-18 19:33:48.000000000 +1100
@@ -1969,9 +1969,6 @@ static void NCR5380_information_transfer
 					 * arbitration can resume.
 					 */
 					NCR5380_write(TARGET_COMMAND_REG, 0);
-
-					while ((NCR5380_read(STATUS_REG) & SR_BSY) && !hostdata->connected)
-						barrier();
 					return;
 				case MESSAGE_REJECT:
 					/* Accept message by clearing ACK */
@@ -2004,10 +2001,6 @@ static void NCR5380_information_transfer
 
 						/* Enable reselect interrupts */
 						NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
-						/* Wait for bus free to avoid nasty timeouts - FIXME timeout !*/
-						/* NCR538_poll_politely(instance, STATUS_REG, SR_BSY, 0, 30 * HZ); */
-						while ((NCR5380_read(STATUS_REG) & SR_BSY) && !hostdata->connected)
-							barrier();
 						return;
 					}
 					/* 
Index: linux/drivers/scsi/atari_NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/atari_NCR5380.c	2015-11-18 19:33:47.000000000 +1100
+++ linux/drivers/scsi/atari_NCR5380.c	2015-11-18 19:33:48.000000000 +1100
@@ -2207,7 +2207,6 @@ static void NCR5380_information_transfer
 						  "completed\n", HOSTNO, cmd->device->id, cmd->device->lun);
 
 					local_irq_save(flags);
-					hostdata->retain_dma_intr++;
 					hostdata->connected = NULL;
 #ifdef SUPPORT_TAGS
 					cmd_free_tag(cmd);
@@ -2276,8 +2275,6 @@ static void NCR5380_information_transfer
 						cmd->scsi_done(cmd);
 					}
 
-					local_irq_restore(flags);
-
 					NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
 					/*
 					 * Restore phase bits to 0 so an interrupted selection,
@@ -2285,11 +2282,6 @@ static void NCR5380_information_transfer
 					 */
 					NCR5380_write(TARGET_COMMAND_REG, 0);
 
-					while ((NCR5380_read(STATUS_REG) & SR_BSY) && !hostdata->connected)
-						barrier();
-
-					local_irq_save(flags);
-					hostdata->retain_dma_intr--;
 					/* ++roman: For Falcon SCSI, release the lock on the
 					 * ST-DMA here if no other commands are waiting on the
 					 * disconnected queue.
@@ -2343,9 +2335,6 @@ static void NCR5380_information_transfer
 
 					/* Enable reselect interrupts */
 					NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
-					/* Wait for bus free to avoid nasty timeouts */
-					while ((NCR5380_read(STATUS_REG) & SR_BSY) && !hostdata->connected)
-						barrier();
 #ifdef SUN3_SCSI_VME
 					dregs->csr |= CSR_DMA_ENABLE;
 #endif

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

* [PATCH 36/71] ncr5380: Use work_struct instead of delayed_work
  2015-11-18  8:34 ` Finn Thain
@ 2015-11-18  8:35   ` Finn Thain
  -1 siblings, 0 replies; 268+ messages in thread
From: Finn Thain @ 2015-11-18  8:35 UTC (permalink / raw)
  To: James E.J. Bottomley, Michael Schmitz, linux-m68k, linux-scsi,
	linux-kernel

[-- Attachment #1: ncr5380-work_struct-instead --]
[-- Type: text/plain, Size: 3123 bytes --]

Each host instance now has it's own work queue so the main() work item can
sleep when necessary. That means we can use a simple work item rather than
a delayed work item. This brings NCR5380.c closer to atari_NCR5380.c.

Signed-off-by: Finn Thain <fthain@telegraphics.com.au>

---
 drivers/scsi/NCR5380.c |   12 +++++-------
 drivers/scsi/NCR5380.h |    1 -
 2 files changed, 5 insertions(+), 8 deletions(-)

Index: linux/drivers/scsi/NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/NCR5380.c	2015-11-18 19:33:48.000000000 +1100
+++ linux/drivers/scsi/NCR5380.c	2015-11-18 19:33:49.000000000 +1100
@@ -705,7 +705,7 @@ static int NCR5380_init(struct Scsi_Host
 	hostdata->issue_queue = NULL;
 	hostdata->disconnected_queue = NULL;
 	
-	INIT_DELAYED_WORK(&hostdata->coroutine, NCR5380_main);
+	INIT_WORK(&hostdata->main_task, NCR5380_main);
 	hostdata->work_q = alloc_workqueue("ncr5380_%d",
 	                        WQ_CPU_INTENSIVE | WQ_UNBOUND | WQ_MEM_RECLAIM,
 	                        1, instance->host_no);
@@ -790,7 +790,7 @@ static void NCR5380_exit(struct Scsi_Hos
 {
 	struct NCR5380_hostdata *hostdata = (struct NCR5380_hostdata *) instance->hostdata;
 
-	cancel_delayed_work_sync(&hostdata->coroutine);
+	cancel_work_sync(&hostdata->main_task);
 	destroy_workqueue(hostdata->work_q);
 }
 
@@ -852,9 +852,8 @@ static int NCR5380_queue_command(struct
 
 	dprintk(NDEBUG_QUEUES, "scsi%d : command added to %s of queue\n", instance->host_no, (cmd->cmnd[0] == REQUEST_SENSE) ? "head" : "tail");
 
-	/* Run the coroutine if it isn't already running. */
 	/* Kick off command processing */
-	queue_delayed_work(hostdata->work_q, &hostdata->coroutine, 0);
+	queue_work(hostdata->work_q, &hostdata->main_task);
 	return 0;
 }
 
@@ -873,7 +872,7 @@ static int NCR5380_queue_command(struct
 static void NCR5380_main(struct work_struct *work)
 {
 	struct NCR5380_hostdata *hostdata =
-		container_of(work, struct NCR5380_hostdata, coroutine.work);
+		container_of(work, struct NCR5380_hostdata, main_task);
 	struct Scsi_Host *instance = hostdata->host;
 	struct scsi_cmnd *tmp, *prev;
 	int done;
@@ -1030,8 +1029,7 @@ static irqreturn_t NCR5380_intr(int dumm
 		}	/* if BASR_IRQ */
 		spin_unlock_irqrestore(instance->host_lock, flags);
 		if(!done)
-			queue_delayed_work(hostdata->work_q,
-			                   &hostdata->coroutine, 0);
+			queue_work(hostdata->work_q, &hostdata->main_task);
 	} while (!done);
 	return IRQ_HANDLED;
 }
Index: linux/drivers/scsi/NCR5380.h
===================================================================
--- linux.orig/drivers/scsi/NCR5380.h	2015-11-18 19:33:38.000000000 +1100
+++ linux/drivers/scsi/NCR5380.h	2015-11-18 19:33:49.000000000 +1100
@@ -256,7 +256,6 @@ struct NCR5380_hostdata {
 	volatile struct scsi_cmnd *issue_queue;	/* waiting to be issued */
 	volatile struct scsi_cmnd *disconnected_queue;	/* waiting for reconnect */
 	int flags;
-	struct delayed_work coroutine;		/* our co-routine */
 	struct scsi_eh_save ses;
 	char info[256];
 	int read_overruns;                /* number of bytes to cut from a



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

* [PATCH 36/71] ncr5380: Use work_struct instead of delayed_work
@ 2015-11-18  8:35   ` Finn Thain
  0 siblings, 0 replies; 268+ messages in thread
From: Finn Thain @ 2015-11-18  8:35 UTC (permalink / raw)
  To: James E.J. Bottomley, Michael Schmitz, linux-m68k, linux-scsi,
	linux-kernel

[-- Attachment #1: ncr5380-work_struct-instead --]
[-- Type: text/plain, Size: 3121 bytes --]

Each host instance now has it's own work queue so the main() work item can
sleep when necessary. That means we can use a simple work item rather than
a delayed work item. This brings NCR5380.c closer to atari_NCR5380.c.

Signed-off-by: Finn Thain <fthain@telegraphics.com.au>

---
 drivers/scsi/NCR5380.c |   12 +++++-------
 drivers/scsi/NCR5380.h |    1 -
 2 files changed, 5 insertions(+), 8 deletions(-)

Index: linux/drivers/scsi/NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/NCR5380.c	2015-11-18 19:33:48.000000000 +1100
+++ linux/drivers/scsi/NCR5380.c	2015-11-18 19:33:49.000000000 +1100
@@ -705,7 +705,7 @@ static int NCR5380_init(struct Scsi_Host
 	hostdata->issue_queue = NULL;
 	hostdata->disconnected_queue = NULL;
 	
-	INIT_DELAYED_WORK(&hostdata->coroutine, NCR5380_main);
+	INIT_WORK(&hostdata->main_task, NCR5380_main);
 	hostdata->work_q = alloc_workqueue("ncr5380_%d",
 	                        WQ_CPU_INTENSIVE | WQ_UNBOUND | WQ_MEM_RECLAIM,
 	                        1, instance->host_no);
@@ -790,7 +790,7 @@ static void NCR5380_exit(struct Scsi_Hos
 {
 	struct NCR5380_hostdata *hostdata = (struct NCR5380_hostdata *) instance->hostdata;
 
-	cancel_delayed_work_sync(&hostdata->coroutine);
+	cancel_work_sync(&hostdata->main_task);
 	destroy_workqueue(hostdata->work_q);
 }
 
@@ -852,9 +852,8 @@ static int NCR5380_queue_command(struct
 
 	dprintk(NDEBUG_QUEUES, "scsi%d : command added to %s of queue\n", instance->host_no, (cmd->cmnd[0] == REQUEST_SENSE) ? "head" : "tail");
 
-	/* Run the coroutine if it isn't already running. */
 	/* Kick off command processing */
-	queue_delayed_work(hostdata->work_q, &hostdata->coroutine, 0);
+	queue_work(hostdata->work_q, &hostdata->main_task);
 	return 0;
 }
 
@@ -873,7 +872,7 @@ static int NCR5380_queue_command(struct
 static void NCR5380_main(struct work_struct *work)
 {
 	struct NCR5380_hostdata *hostdata =
-		container_of(work, struct NCR5380_hostdata, coroutine.work);
+		container_of(work, struct NCR5380_hostdata, main_task);
 	struct Scsi_Host *instance = hostdata->host;
 	struct scsi_cmnd *tmp, *prev;
 	int done;
@@ -1030,8 +1029,7 @@ static irqreturn_t NCR5380_intr(int dumm
 		}	/* if BASR_IRQ */
 		spin_unlock_irqrestore(instance->host_lock, flags);
 		if(!done)
-			queue_delayed_work(hostdata->work_q,
-			                   &hostdata->coroutine, 0);
+			queue_work(hostdata->work_q, &hostdata->main_task);
 	} while (!done);
 	return IRQ_HANDLED;
 }
Index: linux/drivers/scsi/NCR5380.h
===================================================================
--- linux.orig/drivers/scsi/NCR5380.h	2015-11-18 19:33:38.000000000 +1100
+++ linux/drivers/scsi/NCR5380.h	2015-11-18 19:33:49.000000000 +1100
@@ -256,7 +256,6 @@ struct NCR5380_hostdata {
 	volatile struct scsi_cmnd *issue_queue;	/* waiting to be issued */
 	volatile struct scsi_cmnd *disconnected_queue;	/* waiting for reconnect */
 	int flags;
-	struct delayed_work coroutine;		/* our co-routine */
 	struct scsi_eh_save ses;
 	char info[256];
 	int read_overruns;                /* number of bytes to cut from a

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

* [PATCH 37/71] ncr5380: Standardize work queueing algorithm
  2015-11-18  8:34 ` Finn Thain
@ 2015-11-18  8:35   ` Finn Thain
  -1 siblings, 0 replies; 268+ messages in thread
From: Finn Thain @ 2015-11-18  8:35 UTC (permalink / raw)
  To: James E.J. Bottomley, Michael Schmitz, linux-m68k, linux-scsi,
	linux-kernel

[-- Attachment #1: atari_NCR5380-main_running-and-queue_main --]
[-- Type: text/plain, Size: 6332 bytes --]

The complex main_running/queue_main mechanism is peculiar to
atari_NCR5380.c. It isn't SMP safe and offers little value given that
the work queue already offers concurrency management. Remove this
complexity to bring atari_NCR5380.c closer to NCR5380.c.

It is not a good idea to call the information transfer state machine from
queuecommand because, according to Documentation/scsi/scsi_mid_low_api.txt
that could happen in soft irq context. Fix this.

Signed-off-by: Finn Thain <fthain@telegraphics.com.au>

---
 drivers/scsi/NCR5380.h       |    1 
 drivers/scsi/atari_NCR5380.c |   80 +++----------------------------------------
 2 files changed, 6 insertions(+), 75 deletions(-)

Index: linux/drivers/scsi/NCR5380.h
===================================================================
--- linux.orig/drivers/scsi/NCR5380.h	2015-11-18 19:33:49.000000000 +1100
+++ linux/drivers/scsi/NCR5380.h	2015-11-18 19:33:51.000000000 +1100
@@ -262,7 +262,6 @@ struct NCR5380_hostdata {
 	                                   * transfer to handle chip overruns */
 	int retain_dma_intr;
 	struct work_struct main_task;
-	volatile int main_running;
 #ifdef SUPPORT_TAGS
 	struct tag_alloc TagAlloc[8][8];	/* 8 targets and 8 LUNs */
 #endif
Index: linux/drivers/scsi/atari_NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/atari_NCR5380.c	2015-11-18 19:33:48.000000000 +1100
+++ linux/drivers/scsi/atari_NCR5380.c	2015-11-18 19:33:51.000000000 +1100
@@ -611,36 +611,6 @@ static void NCR5380_print_phase(struct S
 
 #endif
 
-/*
- * ++roman: New scheme of calling NCR5380_main()
- *
- * If we're not in an interrupt, we can call our main directly, it cannot be
- * already running. Else, we queue it on a task queue, if not 'main_running'
- * tells us that a lower level is already executing it. This way,
- * 'main_running' needs not be protected in a special way.
- *
- * queue_main() is a utility function for putting our main onto the task
- * queue, if main_running is false. It should be called only from a
- * interrupt or bottom half.
- */
-
-#include <linux/gfp.h>
-#include <linux/workqueue.h>
-#include <linux/interrupt.h>
-
-static inline void queue_main(struct NCR5380_hostdata *hostdata)
-{
-	if (!hostdata->main_running) {
-		/* If in interrupt and NCR5380_main() not already running,
-		   queue it on the 'immediate' task queue, to be processed
-		   immediately after the current interrupt processing has
-		   finished. */
-		queue_work(hostdata->work_q, &hostdata->main_task);
-	}
-	/* else: nothing to do: the running NCR5380_main() will pick up
-	   any newly queued command. */
-}
-
 /**
  * NCR58380_info - report driver and host information
  * @instance: relevant scsi host instance
@@ -723,8 +693,6 @@ static void __maybe_unused NCR5380_print
 	hostdata = (struct NCR5380_hostdata *)instance->hostdata;
 
 	local_irq_save(flags);
-	printk("NCR5380: coroutine is%s running.\n",
-		hostdata->main_running ? "" : "n't");
 	if (!hostdata->connected)
 		printk("scsi%d: no currently connected command\n", HOSTNO);
 	else
@@ -766,8 +734,6 @@ static int __maybe_unused NCR5380_show_i
 	hostdata = (struct NCR5380_hostdata *)instance->hostdata;
 
 	local_irq_save(flags);
-	seq_printf(m, "NCR5380: coroutine is%s running.\n",
-		hostdata->main_running ? "" : "n't");
 	if (!hostdata->connected)
 		seq_printf(m, "scsi%d: no currently connected command\n", HOSTNO);
 	else
@@ -991,17 +957,8 @@ static int NCR5380_queue_command(struct
 	dprintk(NDEBUG_QUEUES, "scsi%d: command added to %s of queue\n", H_NO(cmd),
 		  (cmd->cmnd[0] == REQUEST_SENSE) ? "head" : "tail");
 
-	/* If queue_command() is called from an interrupt (real one or bottom
-	 * half), we let queue_main() do the job of taking care about main. If it
-	 * is already running, this is a no-op, else main will be queued.
-	 *
-	 * If we're not in an interrupt, we can call NCR5380_main()
-	 * unconditionally, because it cannot be already running.
-	 */
-	if (in_interrupt() || irqs_disabled())
-		queue_main(hostdata);
-	else
-		NCR5380_main(&hostdata->main_task);
+	/* Kick off command processing */
+	queue_work(hostdata->work_q, &hostdata->main_task);
 	return 0;
 }
 
@@ -1038,30 +995,11 @@ static void NCR5380_main(struct work_str
 	unsigned long flags;
 
 	/*
-	 * We run (with interrupts disabled) until we're sure that none of
-	 * the host adapters have anything that can be done, at which point
-	 * we set main_running to 0 and exit.
-	 *
-	 * Interrupts are enabled before doing various other internal
-	 * instructions, after we've decided that we need to run through
-	 * the loop again.
-	 *
-	 * this should prevent any race conditions.
-	 *
 	 * ++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.
 	 */
 
-	/* Tell int handlers main() is now already executing.  Note that
-	   no races are possible here. If an int comes in before
-	   'main_running' is set here, and queues/executes main via the
-	   task queue, it doesn't do any harm, just this instance of main
-	   won't find any work left to do. */
-	if (hostdata->main_running)
-		return;
-	hostdata->main_running = 1;
-
 	local_save_flags(flags);
 	do {
 		local_irq_disable();	/* Freeze request queues */
@@ -1176,11 +1114,6 @@ static void NCR5380_main(struct work_str
 			done = 0;
 		}
 	} while (!done);
-
-	/* Better allow ints _after_ 'main_running' has been cleared, else
-	   an interrupt could believe we'll pick up the work it left for
-	   us, but we won't see it anymore here... */
-	hostdata->main_running = 0;
 	local_irq_restore(flags);
 }
 
@@ -1293,6 +1226,7 @@ static void NCR5380_dma_complete(struct
 static irqreturn_t NCR5380_intr(int irq, void *dev_id)
 {
 	struct Scsi_Host *instance = dev_id;
+	struct NCR5380_hostdata *hostdata = shost_priv(instance);
 	int done = 1, handled = 0;
 	unsigned char basr;
 
@@ -1361,11 +1295,9 @@ static irqreturn_t NCR5380_intr(int irq,
 #endif
 	}
 
-	if (!done) {
-		dprintk(NDEBUG_INTR, "scsi%d: in int routine, calling main\n", HOSTNO);
-		/* Put a call to NCR5380_main() on the queue... */
-		queue_main(shost_priv(instance));
-	}
+	if (!done)
+		queue_work(hostdata->work_q, &hostdata->main_task);
+
 	return IRQ_RETVAL(handled);
 }
 



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

* [PATCH 37/71] ncr5380: Standardize work queueing algorithm
@ 2015-11-18  8:35   ` Finn Thain
  0 siblings, 0 replies; 268+ messages in thread
From: Finn Thain @ 2015-11-18  8:35 UTC (permalink / raw)
  To: James E.J. Bottomley, Michael Schmitz, linux-m68k, linux-scsi,
	linux-kernel

[-- Attachment #1: atari_NCR5380-main_running-and-queue_main --]
[-- Type: text/plain, Size: 6330 bytes --]

The complex main_running/queue_main mechanism is peculiar to
atari_NCR5380.c. It isn't SMP safe and offers little value given that
the work queue already offers concurrency management. Remove this
complexity to bring atari_NCR5380.c closer to NCR5380.c.

It is not a good idea to call the information transfer state machine from
queuecommand because, according to Documentation/scsi/scsi_mid_low_api.txt
that could happen in soft irq context. Fix this.

Signed-off-by: Finn Thain <fthain@telegraphics.com.au>

---
 drivers/scsi/NCR5380.h       |    1 
 drivers/scsi/atari_NCR5380.c |   80 +++----------------------------------------
 2 files changed, 6 insertions(+), 75 deletions(-)

Index: linux/drivers/scsi/NCR5380.h
===================================================================
--- linux.orig/drivers/scsi/NCR5380.h	2015-11-18 19:33:49.000000000 +1100
+++ linux/drivers/scsi/NCR5380.h	2015-11-18 19:33:51.000000000 +1100
@@ -262,7 +262,6 @@ struct NCR5380_hostdata {
 	                                   * transfer to handle chip overruns */
 	int retain_dma_intr;
 	struct work_struct main_task;
-	volatile int main_running;
 #ifdef SUPPORT_TAGS
 	struct tag_alloc TagAlloc[8][8];	/* 8 targets and 8 LUNs */
 #endif
Index: linux/drivers/scsi/atari_NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/atari_NCR5380.c	2015-11-18 19:33:48.000000000 +1100
+++ linux/drivers/scsi/atari_NCR5380.c	2015-11-18 19:33:51.000000000 +1100
@@ -611,36 +611,6 @@ static void NCR5380_print_phase(struct S
 
 #endif
 
-/*
- * ++roman: New scheme of calling NCR5380_main()
- *
- * If we're not in an interrupt, we can call our main directly, it cannot be
- * already running. Else, we queue it on a task queue, if not 'main_running'
- * tells us that a lower level is already executing it. This way,
- * 'main_running' needs not be protected in a special way.
- *
- * queue_main() is a utility function for putting our main onto the task
- * queue, if main_running is false. It should be called only from a
- * interrupt or bottom half.
- */
-
-#include <linux/gfp.h>
-#include <linux/workqueue.h>
-#include <linux/interrupt.h>
-
-static inline void queue_main(struct NCR5380_hostdata *hostdata)
-{
-	if (!hostdata->main_running) {
-		/* If in interrupt and NCR5380_main() not already running,
-		   queue it on the 'immediate' task queue, to be processed
-		   immediately after the current interrupt processing has
-		   finished. */
-		queue_work(hostdata->work_q, &hostdata->main_task);
-	}
-	/* else: nothing to do: the running NCR5380_main() will pick up
-	   any newly queued command. */
-}
-
 /**
  * NCR58380_info - report driver and host information
  * @instance: relevant scsi host instance
@@ -723,8 +693,6 @@ static void __maybe_unused NCR5380_print
 	hostdata = (struct NCR5380_hostdata *)instance->hostdata;
 
 	local_irq_save(flags);
-	printk("NCR5380: coroutine is%s running.\n",
-		hostdata->main_running ? "" : "n't");
 	if (!hostdata->connected)
 		printk("scsi%d: no currently connected command\n", HOSTNO);
 	else
@@ -766,8 +734,6 @@ static int __maybe_unused NCR5380_show_i
 	hostdata = (struct NCR5380_hostdata *)instance->hostdata;
 
 	local_irq_save(flags);
-	seq_printf(m, "NCR5380: coroutine is%s running.\n",
-		hostdata->main_running ? "" : "n't");
 	if (!hostdata->connected)
 		seq_printf(m, "scsi%d: no currently connected command\n", HOSTNO);
 	else
@@ -991,17 +957,8 @@ static int NCR5380_queue_command(struct
 	dprintk(NDEBUG_QUEUES, "scsi%d: command added to %s of queue\n", H_NO(cmd),
 		  (cmd->cmnd[0] == REQUEST_SENSE) ? "head" : "tail");
 
-	/* If queue_command() is called from an interrupt (real one or bottom
-	 * half), we let queue_main() do the job of taking care about main. If it
-	 * is already running, this is a no-op, else main will be queued.
-	 *
-	 * If we're not in an interrupt, we can call NCR5380_main()
-	 * unconditionally, because it cannot be already running.
-	 */
-	if (in_interrupt() || irqs_disabled())
-		queue_main(hostdata);
-	else
-		NCR5380_main(&hostdata->main_task);
+	/* Kick off command processing */
+	queue_work(hostdata->work_q, &hostdata->main_task);
 	return 0;
 }
 
@@ -1038,30 +995,11 @@ static void NCR5380_main(struct work_str
 	unsigned long flags;
 
 	/*
-	 * We run (with interrupts disabled) until we're sure that none of
-	 * the host adapters have anything that can be done, at which point
-	 * we set main_running to 0 and exit.
-	 *
-	 * Interrupts are enabled before doing various other internal
-	 * instructions, after we've decided that we need to run through
-	 * the loop again.
-	 *
-	 * this should prevent any race conditions.
-	 *
 	 * ++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.
 	 */
 
-	/* Tell int handlers main() is now already executing.  Note that
-	   no races are possible here. If an int comes in before
-	   'main_running' is set here, and queues/executes main via the
-	   task queue, it doesn't do any harm, just this instance of main
-	   won't find any work left to do. */
-	if (hostdata->main_running)
-		return;
-	hostdata->main_running = 1;
-
 	local_save_flags(flags);
 	do {
 		local_irq_disable();	/* Freeze request queues */
@@ -1176,11 +1114,6 @@ static void NCR5380_main(struct work_str
 			done = 0;
 		}
 	} while (!done);
-
-	/* Better allow ints _after_ 'main_running' has been cleared, else
-	   an interrupt could believe we'll pick up the work it left for
-	   us, but we won't see it anymore here... */
-	hostdata->main_running = 0;
 	local_irq_restore(flags);
 }
 
@@ -1293,6 +1226,7 @@ static void NCR5380_dma_complete(struct
 static irqreturn_t NCR5380_intr(int irq, void *dev_id)
 {
 	struct Scsi_Host *instance = dev_id;
+	struct NCR5380_hostdata *hostdata = shost_priv(instance);
 	int done = 1, handled = 0;
 	unsigned char basr;
 
@@ -1361,11 +1295,9 @@ static irqreturn_t NCR5380_intr(int irq,
 #endif
 	}
 
-	if (!done) {
-		dprintk(NDEBUG_INTR, "scsi%d: in int routine, calling main\n", HOSTNO);
-		/* Put a call to NCR5380_main() on the queue... */
-		queue_main(shost_priv(instance));
-	}
+	if (!done)
+		queue_work(hostdata->work_q, &hostdata->main_task);
+
 	return IRQ_RETVAL(handled);
 }
 

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

* [PATCH 38/71] ncr5380: Remove UNSAFE macro
  2015-11-18  8:34 ` Finn Thain
@ 2015-11-18  8:35   ` Finn Thain
  -1 siblings, 0 replies; 268+ messages in thread
From: Finn Thain @ 2015-11-18  8:35 UTC (permalink / raw)
  To: James E.J. Bottomley, Michael Schmitz, linux-m68k, linux-scsi,
	linux-kernel

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

Configuring core drivers using macros like this one prevents re-unifying
the core driver forks, and prevents implementing the core driver as a
library or a platform driver.

The UNSAFE macro in particular is a poor workaround for the problem of
interrupt latency. Releasing the locks complicates things because then we
would have to handle the possibility of EH handler invocation during a
PDMA transfer.

The comments say that instead of using this macro, "you're going to be
better off twiddling with transfersize". I agree. Remove this stuff.

Signed-off-by: Finn Thain <fthain@telegraphics.com.au>

---
 drivers/scsi/NCR5380.c |   15 ---------------
 drivers/scsi/dtc.c     |    2 --
 drivers/scsi/pas16.c   |    1 -
 3 files changed, 18 deletions(-)

Index: linux/drivers/scsi/NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/NCR5380.c	2015-11-18 19:33:49.000000000 +1100
+++ linux/drivers/scsi/NCR5380.c	2015-11-18 19:33:52.000000000 +1100
@@ -195,12 +195,6 @@
  *      rely on phase mismatch and EOP interrupts to determine end 
  *      of phase.
  *
- * UNSAFE - leave interrupts enabled during pseudo-DMA transfers.  You
- *          only really want to use this if you're having a problem with
- *          dropped characters during high speed communications, and even
- *          then, you're going to be better off twiddling with transfersize
- *          in the high level code.
- *
  * Defaults for these will be provided although the user may want to adjust 
  * these to allocate CPU resources to the SCSI driver or "real" code.
  * 
@@ -563,9 +557,6 @@ static void prepare_info(struct Scsi_Hos
 #ifdef PSEUDO_DMA
 	         "PSEUDO_DMA "
 #endif
-#ifdef UNSAFE
-	         "UNSAFE "
-#endif
 	         "");
 }
 
@@ -1575,9 +1566,6 @@ static int NCR5380_transfer_dma(struct S
 	 * before the setting of DMA mode to after transfer of the last byte.
 	 */
 
-#if defined(PSEUDO_DMA) && defined(UNSAFE)
-	spin_unlock_irq(instance->host_lock);
-#endif
 	/* KLL May need eop and parity in 53c400 */
 	if (hostdata->flags & FLAG_NCR53C400)
 		NCR5380_write(MODE_REG, MR_BASE | MR_DMA_MODE |
@@ -1786,9 +1774,6 @@ static int NCR5380_transfer_dma(struct S
 	*data = d + c;
 	*count = 0;
 	*phase = NCR5380_read(STATUS_REG) & PHASE_MASK;
-#if defined(PSEUDO_DMA) && defined(UNSAFE)
-	spin_lock_irq(instance->host_lock);
-#endif				/* defined(REAL_DMA_POLL) */
 	return foo;
 #endif				/* def REAL_DMA */
 }
Index: linux/drivers/scsi/dtc.c
===================================================================
--- linux.orig/drivers/scsi/dtc.c	2015-11-18 19:33:35.000000000 +1100
+++ linux/drivers/scsi/dtc.c	2015-11-18 19:33:52.000000000 +1100
@@ -1,7 +1,5 @@
-
 #define PSEUDO_DMA
 #define DONT_USE_INTR
-#define UNSAFE			/* Leave interrupts enabled during pseudo-dma I/O */
 #define DMA_WORKS_RIGHT
 
 
Index: linux/drivers/scsi/pas16.c
===================================================================
--- linux.orig/drivers/scsi/pas16.c	2015-11-18 19:33:27.000000000 +1100
+++ linux/drivers/scsi/pas16.c	2015-11-18 19:33:52.000000000 +1100
@@ -1,5 +1,4 @@
 #define PSEUDO_DMA
-#define UNSAFE  /* Not unsafe for PAS16 -- use it */
 
 /*
  * This driver adapted from Drew Eckhardt's Trantor T128 driver



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

* [PATCH 38/71] ncr5380: Remove UNSAFE macro
@ 2015-11-18  8:35   ` Finn Thain
  0 siblings, 0 replies; 268+ messages in thread
From: Finn Thain @ 2015-11-18  8:35 UTC (permalink / raw)
  To: James E.J. Bottomley, Michael Schmitz, linux-m68k, linux-scsi,
	linux-kernel

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

Configuring core drivers using macros like this one prevents re-unifying
the core driver forks, and prevents implementing the core driver as a
library or a platform driver.

The UNSAFE macro in particular is a poor workaround for the problem of
interrupt latency. Releasing the locks complicates things because then we
would have to handle the possibility of EH handler invocation during a
PDMA transfer.

The comments say that instead of using this macro, "you're going to be
better off twiddling with transfersize". I agree. Remove this stuff.

Signed-off-by: Finn Thain <fthain@telegraphics.com.au>

---
 drivers/scsi/NCR5380.c |   15 ---------------
 drivers/scsi/dtc.c     |    2 --
 drivers/scsi/pas16.c   |    1 -
 3 files changed, 18 deletions(-)

Index: linux/drivers/scsi/NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/NCR5380.c	2015-11-18 19:33:49.000000000 +1100
+++ linux/drivers/scsi/NCR5380.c	2015-11-18 19:33:52.000000000 +1100
@@ -195,12 +195,6 @@
  *      rely on phase mismatch and EOP interrupts to determine end 
  *      of phase.
  *
- * UNSAFE - leave interrupts enabled during pseudo-DMA transfers.  You
- *          only really want to use this if you're having a problem with
- *          dropped characters during high speed communications, and even
- *          then, you're going to be better off twiddling with transfersize
- *          in the high level code.
- *
  * Defaults for these will be provided although the user may want to adjust 
  * these to allocate CPU resources to the SCSI driver or "real" code.
  * 
@@ -563,9 +557,6 @@ static void prepare_info(struct Scsi_Hos
 #ifdef PSEUDO_DMA
 	         "PSEUDO_DMA "
 #endif
-#ifdef UNSAFE
-	         "UNSAFE "
-#endif
 	         "");
 }
 
@@ -1575,9 +1566,6 @@ static int NCR5380_transfer_dma(struct S
 	 * before the setting of DMA mode to after transfer of the last byte.
 	 */
 
-#if defined(PSEUDO_DMA) && defined(UNSAFE)
-	spin_unlock_irq(instance->host_lock);
-#endif
 	/* KLL May need eop and parity in 53c400 */
 	if (hostdata->flags & FLAG_NCR53C400)
 		NCR5380_write(MODE_REG, MR_BASE | MR_DMA_MODE |
@@ -1786,9 +1774,6 @@ static int NCR5380_transfer_dma(struct S
 	*data = d + c;
 	*count = 0;
 	*phase = NCR5380_read(STATUS_REG) & PHASE_MASK;
-#if defined(PSEUDO_DMA) && defined(UNSAFE)
-	spin_lock_irq(instance->host_lock);
-#endif				/* defined(REAL_DMA_POLL) */
 	return foo;
 #endif				/* def REAL_DMA */
 }
Index: linux/drivers/scsi/dtc.c
===================================================================
--- linux.orig/drivers/scsi/dtc.c	2015-11-18 19:33:35.000000000 +1100
+++ linux/drivers/scsi/dtc.c	2015-11-18 19:33:52.000000000 +1100
@@ -1,7 +1,5 @@
-
 #define PSEUDO_DMA
 #define DONT_USE_INTR
-#define UNSAFE			/* Leave interrupts enabled during pseudo-dma I/O */
 #define DMA_WORKS_RIGHT
 
 
Index: linux/drivers/scsi/pas16.c
===================================================================
--- linux.orig/drivers/scsi/pas16.c	2015-11-18 19:33:27.000000000 +1100
+++ linux/drivers/scsi/pas16.c	2015-11-18 19:33:52.000000000 +1100
@@ -1,5 +1,4 @@
 #define PSEUDO_DMA
-#define UNSAFE  /* Not unsafe for PAS16 -- use it */
 
 /*
  * This driver adapted from Drew Eckhardt's Trantor T128 driver

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

* [PATCH 39/71] ncr5380: Standardize interrupt handling
  2015-11-18  8:34 ` Finn Thain
@ 2015-11-18  8:35   ` Finn Thain
  -1 siblings, 0 replies; 268+ messages in thread
From: Finn Thain @ 2015-11-18  8:35 UTC (permalink / raw)
  To: James E.J. Bottomley, Michael Schmitz, linux-m68k, linux-scsi,
	linux-kernel

[-- Attachment #1: ncr5380-standardize-interrupt-handling --]
[-- Type: text/plain, Size: 23616 bytes --]

Because interrupt handling is crucial to the core driver(s), all wrapper
drivers need to agree on this code. This patch removes discrepancies.

NCR5380_intr() in NCR5380.c has the following pointless loop that differs
from the code in atari_NCR5380.c.

	done = 1;
	do {
		/* ... */
	} while (!done);

The 'done' flag gets cleared when a reconnected command is to be processed
from the work queue. But in NCR5380.c, the flag is also used to cause the
interrupt conditions to be re-examined. Perhaps this was because
NCR5380_reselect() was expected to cause another interrupt, or perhaps
the remaining present interrupt conditions need to be handled after the
NCR5380_reselect() call?

Actually, both possibilities are bogus, as is the loop itself. It seems
have been overlooked in the hit-and-miss removal of scsi host instance
list iteration many years ago; see history/history.git commit 491447e1fcff
("[PATCH] next NCR5380 updates") and commit 69e1a9482e57 ("[PATCH] fix up
NCR5380 private data"). See also my earlier patch, "Always retry
arbitration and selection".

The datasheet says, "IRQ can be reset simply by reading the Reset
Parity/Interrupt Register". So don't treat the chip IRQ like a
level-triggered interrupt. Of the conditions that set the IRQ flag,
some are level-triggered and some are edge-triggered, which means IRQ
itself must be edge-triggered.

Some interrupt conditions are latched and some are not. Before clearing
the chip IRQ flag, clear all state that may cause it to be raised. That
means clearing the DMA Mode and Busy Monitor bits in the Mode Register
and clearing the host ID in the Select Enable register.

Also clean up some printk's and some comments. Keep atari_NCR5380.c and
NCR5380.c in agreement.

Signed-off-by: Finn Thain <fthain@telegraphics.com.au>

---
 drivers/scsi/NCR5380.c       |  187 +++++++++++++++++++++++--------------------
 drivers/scsi/atari_NCR5380.c |  156 +++++++++++++++++------------------
 drivers/scsi/dtc.c           |    8 -
 drivers/scsi/g_NCR5380.c     |    2 
 4 files changed, 180 insertions(+), 173 deletions(-)

Index: linux/drivers/scsi/NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/NCR5380.c	2015-11-18 19:33:52.000000000 +1100
+++ linux/drivers/scsi/NCR5380.c	2015-11-18 19:33:53.000000000 +1100
@@ -944,85 +944,114 @@ static void NCR5380_main(struct work_str
 #ifndef DONT_USE_INTR
 
 /**
- * 	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.
- *
- *	Locks: takes the needed instance locks
+ * 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 dummy, void *dev_id)
+static irqreturn_t NCR5380_intr(int irq, void *dev_id)
 {
 	struct Scsi_Host *instance = dev_id;
-	struct NCR5380_hostdata *hostdata = (struct NCR5380_hostdata *) instance->hostdata;
-	int done;
+	struct NCR5380_hostdata *hostdata = shost_priv(instance);
+	int handled = 0;
 	unsigned char basr;
 	unsigned long flags;
 
-	dprintk(NDEBUG_INTR, "scsi : NCR5380 irq %d triggered\n",
-		instance->irq);
+	spin_lock_irqsave(instance->host_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);
+
+		dprintk(NDEBUG_INTR, "scsi%d: IRQ %d, BASR 0x%02x, SR 0x%02x, MR 0x%02x\n",
+		        instance->host_no, irq, basr, sr, mr);
 
-	do {
-		done = 1;
-		spin_lock_irqsave(instance->host_lock, flags);
-		/* Look for pending interrupts */
-		basr = NCR5380_read(BUS_AND_STATUS_REG);
-		/* XXX dispatch to appropriate routine if found and done=0 */
-		if (basr & BASR_IRQ) {
-			NCR5380_dprint(NDEBUG_INTR, instance);
-			if ((NCR5380_read(STATUS_REG) & (SR_SEL | SR_IO)) == (SR_SEL | SR_IO)) {
-				done = 0;
-				dprintk(NDEBUG_INTR, "scsi%d : SEL interrupt\n", instance->host_no);
-				NCR5380_reselect(instance);
-				(void) NCR5380_read(RESET_PARITY_INTERRUPT_REG);
-			} else if (basr & BASR_PARITY_ERROR) {
-				dprintk(NDEBUG_INTR, "scsi%d : PARITY interrupt\n", instance->host_no);
-				(void) NCR5380_read(RESET_PARITY_INTERRUPT_REG);
-			} else if ((NCR5380_read(STATUS_REG) & SR_RST) == SR_RST) {
-				dprintk(NDEBUG_INTR, "scsi%d : RESET interrupt\n", instance->host_no);
-				(void) NCR5380_read(RESET_PARITY_INTERRUPT_REG);
-			} else {
 #if defined(REAL_DMA)
-				/*
-				 * We should only get PHASE MISMATCH and EOP interrupts
-				 * if we have DMA enabled, so do a sanity check based on
-				 * the current setting of the MODE register.
-				 */
+		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.
+			 */
 
-				if ((NCR5380_read(MODE_REG) & MR_DMA) && ((basr & BASR_END_DMA_TRANSFER) || !(basr & BASR_PHASE_MATCH))) {
-					int transferred;
+			dprintk(NDEBUG_INTR, "scsi%d: interrupt in DMA mode\n", intance->host_no);
 
-					if (!hostdata->connected)
-						panic("scsi%d : received end of DMA interrupt with no connected cmd\n", instance->hostno);
+			int transferred;
 
-					transferred = (hostdata->dmalen - NCR5380_dma_residual(instance));
-					hostdata->connected->SCp.this_residual -= transferred;
-					hostdata->connected->SCp.ptr += transferred;
-					hostdata->dmalen = 0;
-
-					(void) NCR5380_read(RESET_PARITY_INTERRUPT_REG);
-							
-					/* FIXME: we need to poll briefly then defer a workqueue task ! */
-					NCR5380_poll_politely(hostdata, BUS_AND_STATUS_REG, BASR_ACK, 0, 2*HZ);
+			if (!hostdata->connected)
+				panic("scsi%d : DMA interrupt with no connected cmd\n",
+				      instance->hostno);
 
-					NCR5380_write(MODE_REG, MR_BASE);
-					NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
-				}
-#else
-				dprintk(NDEBUG_INTR, "scsi : unknown interrupt, BASR 0x%X, MR 0x%X, SR 0x%x\n", basr, NCR5380_read(MODE_REG), NCR5380_read(STATUS_REG));
-				(void) NCR5380_read(RESET_PARITY_INTERRUPT_REG);
-#endif
+			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 */
+			NCR5380_write(SELECT_ENABLE_REG, 0);
+			NCR5380_read(RESET_PARITY_INTERRUPT_REG);
+
+			dprintk(NDEBUG_INTR, "scsi%d: interrupt with SEL and IO\n",
+			        instance->host_no);
+
+			if (!hostdata->connected) {
+				NCR5380_reselect(instance);
+				queue_work(hostdata->work_q, &hostdata->main_task);
 			}
-		}	/* if BASR_IRQ */
-		spin_unlock_irqrestore(instance->host_lock, flags);
-		if(!done)
-			queue_work(hostdata->work_q, &hostdata->main_task);
-	} while (!done);
-	return IRQ_HANDLED;
+			if (!hostdata->connected)
+				NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
+		} else {
+			/* Probably Bus Reset */
+			NCR5380_read(RESET_PARITY_INTERRUPT_REG);
+
+			dprintk(NDEBUG_INTR, "scsi%d: unknown interrupt\n", instance->host_no);
+		}
+		handled = 1;
+	} else {
+		shost_printk(KERN_NOTICE, instance, "interrupt without IRQ bit\n");
+	}
+
+	spin_unlock_irqrestore(instance->host_lock, flags);
+
+	return IRQ_RETVAL(handled);
 }
 
 #endif 
@@ -1211,8 +1240,9 @@ static int NCR5380_select(struct Scsi_Ho
 	if ((NCR5380_read(STATUS_REG) & (SR_SEL | SR_IO)) == (SR_SEL | SR_IO)) {
 		NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
 		NCR5380_reselect(instance);
+		if (!hostdata->connected)
+			NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
 		printk("scsi%d : reselection after won arbitration?\n", instance->host_no);
-		NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
 		return -1;
 	}
 
@@ -1556,9 +1586,10 @@ static int NCR5380_transfer_dma(struct S
 	NCR5380_write(TARGET_COMMAND_REG, PHASE_SR_TO_TCR(p));
 
 #ifdef REAL_DMA
-	NCR5380_write(MODE_REG, MR_BASE | MR_DMA_MODE | MR_ENABLE_EOP_INTR | MR_MONITOR_BSY);
+	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);
+	NCR5380_write(MODE_REG, MR_BASE | MR_DMA_MODE | MR_MONITOR_BSY);
 #else
 	/*
 	 * Note : on my sample board, watch-dog timeouts occurred when interrupts
@@ -1566,13 +1597,11 @@ static int NCR5380_transfer_dma(struct S
 	 * before the setting of DMA mode to after transfer of the last byte.
 	 */
 
-	/* KLL May need eop and parity in 53c400 */
 	if (hostdata->flags & FLAG_NCR53C400)
-		NCR5380_write(MODE_REG, MR_BASE | MR_DMA_MODE |
-				MR_ENABLE_PAR_CHECK | MR_ENABLE_PAR_INTR |
-				MR_ENABLE_EOP_INTR | MR_MONITOR_BSY);
+		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);
+		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));
@@ -1761,16 +1790,7 @@ static int NCR5380_transfer_dma(struct S
 	}
 	NCR5380_write(MODE_REG, MR_BASE);
 	NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
-
-	if ((!(p & SR_IO)) && (hostdata->flags & FLAG_NCR53C400)) {
-		dprintk(NDEBUG_C400_PWRITE, "53C400w: Checking for IRQ\n");
-		if (NCR5380_read(BUS_AND_STATUS_REG) & BASR_IRQ) {
-			dprintk(NDEBUG_C400_PWRITE, "53C400w:    got it, reading reset interrupt reg\n");
-			NCR5380_read(RESET_PARITY_INTERRUPT_REG);
-		} else {
-			printk("53C400w:    IRQ NOT THERE!\n");
-		}
-	}
+	NCR5380_read(RESET_PARITY_INTERRUPT_REG);
 	*data = d + c;
 	*count = 0;
 	*phase = NCR5380_read(STATUS_REG) & PHASE_MASK;
@@ -2262,7 +2282,6 @@ static void NCR5380_dma_complete(NCR5380
 
 	NCR5380_poll_politely(instance, BUS_AND_STATUS_REG, BASR_ACK, 0, 5*HZ);
 
-	NCR5380_write(MODE_REG, MR_BASE);
 	NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
 
 	/*
Index: linux/drivers/scsi/atari_NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/atari_NCR5380.c	2015-11-18 19:33:51.000000000 +1100
+++ linux/drivers/scsi/atari_NCR5380.c	2015-11-18 19:33:53.000000000 +1100
@@ -1138,12 +1138,6 @@ static void NCR5380_dma_complete(struct
 	int saved_data = 0, overrun = 0;
 	unsigned char p;
 
-	if (!hostdata->connected) {
-		printk(KERN_WARNING "scsi%d: received end of DMA interrupt with "
-		       "no connected cmd\n", HOSTNO);
-		return;
-	}
-
 	if (hostdata->read_overruns) {
 		p = hostdata->connected->SCp.phase;
 		if (p & SR_IO) {
@@ -1158,10 +1152,6 @@ static void NCR5380_dma_complete(struct
 		}
 	}
 
-	dprintk(NDEBUG_DMA, "scsi%d: real DMA transfer complete, basr 0x%X, sr 0x%X\n",
-		   HOSTNO, NCR5380_read(BUS_AND_STATUS_REG),
-		   NCR5380_read(STATUS_REG));
-
 #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",
@@ -1180,9 +1170,9 @@ static void NCR5380_dma_complete(struct
 	}
 #endif
 
-	(void)NCR5380_read(RESET_PARITY_INTERRUPT_REG);
 	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;
@@ -1221,83 +1211,97 @@ static void NCR5380_dma_complete(struct
  * 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 done = 1, handled = 0;
+	int handled = 0;
 	unsigned char basr;
 
-	dprintk(NDEBUG_INTR, "scsi%d: NCR5380 irq triggered\n", HOSTNO);
-
-	/* Look for pending interrupts */
 	basr = NCR5380_read(BUS_AND_STATUS_REG);
-	dprintk(NDEBUG_INTR, "scsi%d: BASR=%02x\n", HOSTNO, basr);
-	/* dispatch to appropriate routine if found and done=0 */
 	if (basr & BASR_IRQ) {
-		NCR5380_dprint(NDEBUG_INTR, instance);
-		if ((NCR5380_read(STATUS_REG) & (SR_SEL|SR_IO)) == (SR_SEL|SR_IO)) {
-			done = 0;
-			dprintk(NDEBUG_INTR, "scsi%d: SEL interrupt\n", HOSTNO);
-			NCR5380_reselect(instance);
-			(void)NCR5380_read(RESET_PARITY_INTERRUPT_REG);
-		} else if (basr & BASR_PARITY_ERROR) {
-			dprintk(NDEBUG_INTR, "scsi%d: PARITY interrupt\n", HOSTNO);
-			(void)NCR5380_read(RESET_PARITY_INTERRUPT_REG);
-		} else if ((NCR5380_read(STATUS_REG) & SR_RST) == SR_RST) {
-			dprintk(NDEBUG_INTR, "scsi%d: RESET interrupt\n", HOSTNO);
-			(void)NCR5380_read(RESET_PARITY_INTERRUPT_REG);
-		} else {
-			/*
-			 * The rest of the interrupt conditions can occur only during a
-			 * DMA transfer
-			 */
+		unsigned char mr = NCR5380_read(MODE_REG);
+		unsigned char sr = NCR5380_read(STATUS_REG);
+
+		dprintk(NDEBUG_INTR, "scsi%d: IRQ %d, BASR 0x%02x, SR 0x%02x, MR 0x%02x\n",
+		        HOSTNO, irq, basr, sr, mr);
 
 #if defined(REAL_DMA)
-			/*
-			 * We should only get PHASE MISMATCH and EOP interrupts if we have
-			 * DMA enabled, so do a sanity check based on the current setting
-			 * of the MODE register.
+		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.
 			 */
 
-			if ((NCR5380_read(MODE_REG) & MR_DMA_MODE) &&
-			    ((basr & BASR_END_DMA_TRANSFER) ||
-			     !(basr & BASR_PHASE_MATCH))) {
-
-				dprintk(NDEBUG_INTR, "scsi%d: PHASE MISM or EOP interrupt\n", HOSTNO);
-				NCR5380_dma_complete( instance );
-				done = 0;
-			} else
+			dprintk(NDEBUG_INTR, "scsi%d: interrupt in DMA mode\n", HOSTNO);
+
+			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
 #endif /* REAL_DMA */
-			{
-/* MS: Ignore unknown phase mismatch interrupts (caused by EOP interrupt) */
-				if (basr & BASR_PHASE_MATCH)
-					dprintk(NDEBUG_INTR, "scsi%d: unknown interrupt, "
-					       "BASR 0x%x, MR 0x%x, SR 0x%x\n",
-					       HOSTNO, basr, NCR5380_read(MODE_REG),
-					       NCR5380_read(STATUS_REG));
-				(void)NCR5380_read(RESET_PARITY_INTERRUPT_REG);
+		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);
+
+			dprintk(NDEBUG_INTR, "scsi%d: interrupt with SEL and IO\n",
+			        HOSTNO);
+
+			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);
+
+			dprintk(NDEBUG_INTR, "scsi%d: unknown interrupt\n", HOSTNO);
 #ifdef SUN3_SCSI_VME
-				dregs->csr |= CSR_DMA_ENABLE;
+			dregs->csr |= CSR_DMA_ENABLE;
 #endif
-			}
-		} /* if !(SELECTION || PARITY) */
+		}
 		handled = 1;
-	} /* BASR & IRQ */ else {
-		printk(KERN_NOTICE "scsi%d: interrupt without IRQ bit set in BASR, "
-		       "BASR 0x%X, MR 0x%X, SR 0x%x\n", HOSTNO, basr,
-		       NCR5380_read(MODE_REG), NCR5380_read(STATUS_REG));
-		(void)NCR5380_read(RESET_PARITY_INTERRUPT_REG);
+	} else {
+		shost_printk(KERN_NOTICE, instance, "interrupt without IRQ bit\n");
 #ifdef SUN3_SCSI_VME
 		dregs->csr |= CSR_DMA_ENABLE;
 #endif
 	}
 
-	if (!done)
-		queue_work(hostdata->work_q, &hostdata->main_task);
-
 	return IRQ_RETVAL(handled);
 }
 
@@ -1503,9 +1507,10 @@ static int NCR5380_select(struct Scsi_Ho
 	if ((NCR5380_read(STATUS_REG) & (SR_SEL | SR_IO)) == (SR_SEL | SR_IO)) {
 		NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
 		NCR5380_reselect(instance);
+		if (!hostdata->connected)
+			NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
 		printk(KERN_ERR "scsi%d: reselection after won arbitration?\n",
 		       HOSTNO);
-		NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
 		return -1;
 	}
 
@@ -1865,19 +1870,14 @@ static int NCR5380_transfer_dma(struct S
 	/* 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(TARGET_COMMAND_REG, 1);
-		NCR5380_read(RESET_PARITY_INTERRUPT_REG);
 		NCR5380_write(INITIATOR_COMMAND_REG, 0);
-		NCR5380_write(MODE_REG,
-			      (NCR5380_read(MODE_REG) | MR_DMA_MODE | MR_ENABLE_EOP_INTR));
 		NCR5380_write(START_DMA_INITIATOR_RECEIVE_REG, 0);
 	} else {
-		NCR5380_write(TARGET_COMMAND_REG, 0);
-		NCR5380_read(RESET_PARITY_INTERRUPT_REG);
 		NCR5380_write(INITIATOR_COMMAND_REG, ICR_ASSERT_DATA);
-		NCR5380_write(MODE_REG,
-			      (NCR5380_read(MODE_REG) | MR_DMA_MODE | MR_ENABLE_EOP_INTR));
 		NCR5380_write(START_DMA_SEND_REG, 0);
 	}
 
@@ -1906,10 +1906,8 @@ static int NCR5380_transfer_dma(struct S
 		   c, (p & SR_IO) ? "to" : "from", d);
 
 	NCR5380_write(TARGET_COMMAND_REG, PHASE_SR_TO_TCR(p));
-
-#ifdef REAL_DMA
-	NCR5380_write(MODE_REG, MR_BASE | MR_DMA_MODE | MR_ENABLE_EOP_INTR | MR_MONITOR_BSY);
-#endif /* def REAL_DMA  */
+	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
@@ -2383,10 +2381,10 @@ static void NCR5380_information_transfer
 #endif
 					hostdata->connected = NULL;
 					cmd->result = DID_ERROR << 16;
-					NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
 					maybe_release_dma_irq(instance);
 					local_irq_restore(flags);
 					cmd->scsi_done(cmd);
+					NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
 					return;
 				}
 				msgout = NOP;
Index: linux/drivers/scsi/dtc.c
===================================================================
--- linux.orig/drivers/scsi/dtc.c	2015-11-18 19:33:52.000000000 +1100
+++ linux/drivers/scsi/dtc.c	2015-11-18 19:33:53.000000000 +1100
@@ -334,8 +334,6 @@ static inline int NCR5380_pread(struct S
 	struct NCR5380_hostdata *hostdata = shost_priv(instance);
 
 	i = 0;
-	NCR5380_read(RESET_PARITY_INTERRUPT_REG);
-	NCR5380_write(MODE_REG, MR_ENABLE_EOP_INTR | MR_DMA_MODE);
 	if (instance->irq == NO_IRQ)
 		NCR5380_write(DTC_CONTROL_REG, CSR_DIR_READ);
 	else
@@ -357,9 +355,7 @@ static inline int NCR5380_pread(struct S
 	rtrc(4);
 	while (!(NCR5380_read(DTC_CONTROL_REG) & D_CR_ACCESS))
 		++i;
-	NCR5380_write(MODE_REG, 0);	/* Clear the operating mode */
 	rtrc(0);
-	NCR5380_read(RESET_PARITY_INTERRUPT_REG);
 	if (i > hostdata->spin_max_r)
 		hostdata->spin_max_r = i;
 	return (0);
@@ -383,9 +379,6 @@ static inline int NCR5380_pwrite(struct
 	int i;
 	struct NCR5380_hostdata *hostdata = shost_priv(instance);
 
-	NCR5380_read(RESET_PARITY_INTERRUPT_REG);
-	NCR5380_write(MODE_REG, MR_ENABLE_EOP_INTR | MR_DMA_MODE);
-	/* set direction (write) */
 	if (instance->irq == NO_IRQ)
 		NCR5380_write(DTC_CONTROL_REG, 0);
 	else
@@ -410,7 +403,6 @@ static inline int NCR5380_pwrite(struct
 		++i;
 	rtrc(7);
 	/* Check for parity error here. fixme. */
-	NCR5380_write(MODE_REG, 0);	/* Clear the operating mode */
 	rtrc(0);
 	if (i > hostdata->spin_max_w)
 		hostdata->spin_max_w = i;
Index: linux/drivers/scsi/g_NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/g_NCR5380.c	2015-11-18 19:33:38.000000000 +1100
+++ linux/drivers/scsi/g_NCR5380.c	2015-11-18 19:33:53.000000000 +1100
@@ -596,8 +596,6 @@ static inline int NCR5380_pread(struct S
 	if (!(NCR5380_read(BUS_AND_STATUS_REG) & BASR_END_DMA_TRANSFER))
 		printk(KERN_ERR "53C400r: no end dma signal\n");
 		
-	NCR5380_write(MODE_REG, MR_BASE);
-	NCR5380_read(RESET_PARITY_INTERRUPT_REG);
 	return 0;
 }
 



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

* [PATCH 39/71] ncr5380: Standardize interrupt handling
@ 2015-11-18  8:35   ` Finn Thain
  0 siblings, 0 replies; 268+ messages in thread
From: Finn Thain @ 2015-11-18  8:35 UTC (permalink / raw)
  To: James E.J. Bottomley, Michael Schmitz, linux-m68k, linux-scsi,
	linux-kernel

[-- Attachment #1: ncr5380-standardize-interrupt-handling --]
[-- Type: text/plain, Size: 23614 bytes --]

Because interrupt handling is crucial to the core driver(s), all wrapper
drivers need to agree on this code. This patch removes discrepancies.

NCR5380_intr() in NCR5380.c has the following pointless loop that differs
from the code in atari_NCR5380.c.

	done = 1;
	do {
		/* ... */
	} while (!done);

The 'done' flag gets cleared when a reconnected command is to be processed
from the work queue. But in NCR5380.c, the flag is also used to cause the
interrupt conditions to be re-examined. Perhaps this was because
NCR5380_reselect() was expected to cause another interrupt, or perhaps
the remaining present interrupt conditions need to be handled after the
NCR5380_reselect() call?

Actually, both possibilities are bogus, as is the loop itself. It seems
have been overlooked in the hit-and-miss removal of scsi host instance
list iteration many years ago; see history/history.git commit 491447e1fcff
("[PATCH] next NCR5380 updates") and commit 69e1a9482e57 ("[PATCH] fix up
NCR5380 private data"). See also my earlier patch, "Always retry
arbitration and selection".

The datasheet says, "IRQ can be reset simply by reading the Reset
Parity/Interrupt Register". So don't treat the chip IRQ like a
level-triggered interrupt. Of the conditions that set the IRQ flag,
some are level-triggered and some are edge-triggered, which means IRQ
itself must be edge-triggered.

Some interrupt conditions are latched and some are not. Before clearing
the chip IRQ flag, clear all state that may cause it to be raised. That
means clearing the DMA Mode and Busy Monitor bits in the Mode Register
and clearing the host ID in the Select Enable register.

Also clean up some printk's and some comments. Keep atari_NCR5380.c and
NCR5380.c in agreement.

Signed-off-by: Finn Thain <fthain@telegraphics.com.au>

---
 drivers/scsi/NCR5380.c       |  187 +++++++++++++++++++++++--------------------
 drivers/scsi/atari_NCR5380.c |  156 +++++++++++++++++------------------
 drivers/scsi/dtc.c           |    8 -
 drivers/scsi/g_NCR5380.c     |    2 
 4 files changed, 180 insertions(+), 173 deletions(-)

Index: linux/drivers/scsi/NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/NCR5380.c	2015-11-18 19:33:52.000000000 +1100
+++ linux/drivers/scsi/NCR5380.c	2015-11-18 19:33:53.000000000 +1100
@@ -944,85 +944,114 @@ static void NCR5380_main(struct work_str
 #ifndef DONT_USE_INTR
 
 /**
- * 	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.
- *
- *	Locks: takes the needed instance locks
+ * 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 dummy, void *dev_id)
+static irqreturn_t NCR5380_intr(int irq, void *dev_id)
 {
 	struct Scsi_Host *instance = dev_id;
-	struct NCR5380_hostdata *hostdata = (struct NCR5380_hostdata *) instance->hostdata;
-	int done;
+	struct NCR5380_hostdata *hostdata = shost_priv(instance);
+	int handled = 0;
 	unsigned char basr;
 	unsigned long flags;
 
-	dprintk(NDEBUG_INTR, "scsi : NCR5380 irq %d triggered\n",
-		instance->irq);
+	spin_lock_irqsave(instance->host_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);
+
+		dprintk(NDEBUG_INTR, "scsi%d: IRQ %d, BASR 0x%02x, SR 0x%02x, MR 0x%02x\n",
+		        instance->host_no, irq, basr, sr, mr);
 
-	do {
-		done = 1;
-		spin_lock_irqsave(instance->host_lock, flags);
-		/* Look for pending interrupts */
-		basr = NCR5380_read(BUS_AND_STATUS_REG);
-		/* XXX dispatch to appropriate routine if found and done=0 */
-		if (basr & BASR_IRQ) {
-			NCR5380_dprint(NDEBUG_INTR, instance);
-			if ((NCR5380_read(STATUS_REG) & (SR_SEL | SR_IO)) == (SR_SEL | SR_IO)) {
-				done = 0;
-				dprintk(NDEBUG_INTR, "scsi%d : SEL interrupt\n", instance->host_no);
-				NCR5380_reselect(instance);
-				(void) NCR5380_read(RESET_PARITY_INTERRUPT_REG);
-			} else if (basr & BASR_PARITY_ERROR) {
-				dprintk(NDEBUG_INTR, "scsi%d : PARITY interrupt\n", instance->host_no);
-				(void) NCR5380_read(RESET_PARITY_INTERRUPT_REG);
-			} else if ((NCR5380_read(STATUS_REG) & SR_RST) == SR_RST) {
-				dprintk(NDEBUG_INTR, "scsi%d : RESET interrupt\n", instance->host_no);
-				(void) NCR5380_read(RESET_PARITY_INTERRUPT_REG);
-			} else {
 #if defined(REAL_DMA)
-				/*
-				 * We should only get PHASE MISMATCH and EOP interrupts
-				 * if we have DMA enabled, so do a sanity check based on
-				 * the current setting of the MODE register.
-				 */
+		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.
+			 */
 
-				if ((NCR5380_read(MODE_REG) & MR_DMA) && ((basr & BASR_END_DMA_TRANSFER) || !(basr & BASR_PHASE_MATCH))) {
-					int transferred;
+			dprintk(NDEBUG_INTR, "scsi%d: interrupt in DMA mode\n", intance->host_no);
 
-					if (!hostdata->connected)
-						panic("scsi%d : received end of DMA interrupt with no connected cmd\n", instance->hostno);
+			int transferred;
 
-					transferred = (hostdata->dmalen - NCR5380_dma_residual(instance));
-					hostdata->connected->SCp.this_residual -= transferred;
-					hostdata->connected->SCp.ptr += transferred;
-					hostdata->dmalen = 0;
-
-					(void) NCR5380_read(RESET_PARITY_INTERRUPT_REG);
-							
-					/* FIXME: we need to poll briefly then defer a workqueue task ! */
-					NCR5380_poll_politely(hostdata, BUS_AND_STATUS_REG, BASR_ACK, 0, 2*HZ);
+			if (!hostdata->connected)
+				panic("scsi%d : DMA interrupt with no connected cmd\n",
+				      instance->hostno);
 
-					NCR5380_write(MODE_REG, MR_BASE);
-					NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
-				}
-#else
-				dprintk(NDEBUG_INTR, "scsi : unknown interrupt, BASR 0x%X, MR 0x%X, SR 0x%x\n", basr, NCR5380_read(MODE_REG), NCR5380_read(STATUS_REG));
-				(void) NCR5380_read(RESET_PARITY_INTERRUPT_REG);
-#endif
+			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 */
+			NCR5380_write(SELECT_ENABLE_REG, 0);
+			NCR5380_read(RESET_PARITY_INTERRUPT_REG);
+
+			dprintk(NDEBUG_INTR, "scsi%d: interrupt with SEL and IO\n",
+			        instance->host_no);
+
+			if (!hostdata->connected) {
+				NCR5380_reselect(instance);
+				queue_work(hostdata->work_q, &hostdata->main_task);
 			}
-		}	/* if BASR_IRQ */
-		spin_unlock_irqrestore(instance->host_lock, flags);
-		if(!done)
-			queue_work(hostdata->work_q, &hostdata->main_task);
-	} while (!done);
-	return IRQ_HANDLED;
+			if (!hostdata->connected)
+				NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
+		} else {
+			/* Probably Bus Reset */
+			NCR5380_read(RESET_PARITY_INTERRUPT_REG);
+
+			dprintk(NDEBUG_INTR, "scsi%d: unknown interrupt\n", instance->host_no);
+		}
+		handled = 1;
+	} else {
+		shost_printk(KERN_NOTICE, instance, "interrupt without IRQ bit\n");
+	}
+
+	spin_unlock_irqrestore(instance->host_lock, flags);
+
+	return IRQ_RETVAL(handled);
 }
 
 #endif 
@@ -1211,8 +1240,9 @@ static int NCR5380_select(struct Scsi_Ho
 	if ((NCR5380_read(STATUS_REG) & (SR_SEL | SR_IO)) == (SR_SEL | SR_IO)) {
 		NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
 		NCR5380_reselect(instance);
+		if (!hostdata->connected)
+			NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
 		printk("scsi%d : reselection after won arbitration?\n", instance->host_no);
-		NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
 		return -1;
 	}
 
@@ -1556,9 +1586,10 @@ static int NCR5380_transfer_dma(struct S
 	NCR5380_write(TARGET_COMMAND_REG, PHASE_SR_TO_TCR(p));
 
 #ifdef REAL_DMA
-	NCR5380_write(MODE_REG, MR_BASE | MR_DMA_MODE | MR_ENABLE_EOP_INTR | MR_MONITOR_BSY);
+	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);
+	NCR5380_write(MODE_REG, MR_BASE | MR_DMA_MODE | MR_MONITOR_BSY);
 #else
 	/*
 	 * Note : on my sample board, watch-dog timeouts occurred when interrupts
@@ -1566,13 +1597,11 @@ static int NCR5380_transfer_dma(struct S
 	 * before the setting of DMA mode to after transfer of the last byte.
 	 */
 
-	/* KLL May need eop and parity in 53c400 */
 	if (hostdata->flags & FLAG_NCR53C400)
-		NCR5380_write(MODE_REG, MR_BASE | MR_DMA_MODE |
-				MR_ENABLE_PAR_CHECK | MR_ENABLE_PAR_INTR |
-				MR_ENABLE_EOP_INTR | MR_MONITOR_BSY);
+		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);
+		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));
@@ -1761,16 +1790,7 @@ static int NCR5380_transfer_dma(struct S
 	}
 	NCR5380_write(MODE_REG, MR_BASE);
 	NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
-
-	if ((!(p & SR_IO)) && (hostdata->flags & FLAG_NCR53C400)) {
-		dprintk(NDEBUG_C400_PWRITE, "53C400w: Checking for IRQ\n");
-		if (NCR5380_read(BUS_AND_STATUS_REG) & BASR_IRQ) {
-			dprintk(NDEBUG_C400_PWRITE, "53C400w:    got it, reading reset interrupt reg\n");
-			NCR5380_read(RESET_PARITY_INTERRUPT_REG);
-		} else {
-			printk("53C400w:    IRQ NOT THERE!\n");
-		}
-	}
+	NCR5380_read(RESET_PARITY_INTERRUPT_REG);
 	*data = d + c;
 	*count = 0;
 	*phase = NCR5380_read(STATUS_REG) & PHASE_MASK;
@@ -2262,7 +2282,6 @@ static void NCR5380_dma_complete(NCR5380
 
 	NCR5380_poll_politely(instance, BUS_AND_STATUS_REG, BASR_ACK, 0, 5*HZ);
 
-	NCR5380_write(MODE_REG, MR_BASE);
 	NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
 
 	/*
Index: linux/drivers/scsi/atari_NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/atari_NCR5380.c	2015-11-18 19:33:51.000000000 +1100
+++ linux/drivers/scsi/atari_NCR5380.c	2015-11-18 19:33:53.000000000 +1100
@@ -1138,12 +1138,6 @@ static void NCR5380_dma_complete(struct
 	int saved_data = 0, overrun = 0;
 	unsigned char p;
 
-	if (!hostdata->connected) {
-		printk(KERN_WARNING "scsi%d: received end of DMA interrupt with "
-		       "no connected cmd\n", HOSTNO);
-		return;
-	}
-
 	if (hostdata->read_overruns) {
 		p = hostdata->connected->SCp.phase;
 		if (p & SR_IO) {
@@ -1158,10 +1152,6 @@ static void NCR5380_dma_complete(struct
 		}
 	}
 
-	dprintk(NDEBUG_DMA, "scsi%d: real DMA transfer complete, basr 0x%X, sr 0x%X\n",
-		   HOSTNO, NCR5380_read(BUS_AND_STATUS_REG),
-		   NCR5380_read(STATUS_REG));
-
 #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",
@@ -1180,9 +1170,9 @@ static void NCR5380_dma_complete(struct
 	}
 #endif
 
-	(void)NCR5380_read(RESET_PARITY_INTERRUPT_REG);
 	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;
@@ -1221,83 +1211,97 @@ static void NCR5380_dma_complete(struct
  * 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 done = 1, handled = 0;
+	int handled = 0;
 	unsigned char basr;
 
-	dprintk(NDEBUG_INTR, "scsi%d: NCR5380 irq triggered\n", HOSTNO);
-
-	/* Look for pending interrupts */
 	basr = NCR5380_read(BUS_AND_STATUS_REG);
-	dprintk(NDEBUG_INTR, "scsi%d: BASR=%02x\n", HOSTNO, basr);
-	/* dispatch to appropriate routine if found and done=0 */
 	if (basr & BASR_IRQ) {
-		NCR5380_dprint(NDEBUG_INTR, instance);
-		if ((NCR5380_read(STATUS_REG) & (SR_SEL|SR_IO)) == (SR_SEL|SR_IO)) {
-			done = 0;
-			dprintk(NDEBUG_INTR, "scsi%d: SEL interrupt\n", HOSTNO);
-			NCR5380_reselect(instance);
-			(void)NCR5380_read(RESET_PARITY_INTERRUPT_REG);
-		} else if (basr & BASR_PARITY_ERROR) {
-			dprintk(NDEBUG_INTR, "scsi%d: PARITY interrupt\n", HOSTNO);
-			(void)NCR5380_read(RESET_PARITY_INTERRUPT_REG);
-		} else if ((NCR5380_read(STATUS_REG) & SR_RST) == SR_RST) {
-			dprintk(NDEBUG_INTR, "scsi%d: RESET interrupt\n", HOSTNO);
-			(void)NCR5380_read(RESET_PARITY_INTERRUPT_REG);
-		} else {
-			/*
-			 * The rest of the interrupt conditions can occur only during a
-			 * DMA transfer
-			 */
+		unsigned char mr = NCR5380_read(MODE_REG);
+		unsigned char sr = NCR5380_read(STATUS_REG);
+
+		dprintk(NDEBUG_INTR, "scsi%d: IRQ %d, BASR 0x%02x, SR 0x%02x, MR 0x%02x\n",
+		        HOSTNO, irq, basr, sr, mr);
 
 #if defined(REAL_DMA)
-			/*
-			 * We should only get PHASE MISMATCH and EOP interrupts if we have
-			 * DMA enabled, so do a sanity check based on the current setting
-			 * of the MODE register.
+		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.
 			 */
 
-			if ((NCR5380_read(MODE_REG) & MR_DMA_MODE) &&
-			    ((basr & BASR_END_DMA_TRANSFER) ||
-			     !(basr & BASR_PHASE_MATCH))) {
-
-				dprintk(NDEBUG_INTR, "scsi%d: PHASE MISM or EOP interrupt\n", HOSTNO);
-				NCR5380_dma_complete( instance );
-				done = 0;
-			} else
+			dprintk(NDEBUG_INTR, "scsi%d: interrupt in DMA mode\n", HOSTNO);
+
+			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
 #endif /* REAL_DMA */
-			{
-/* MS: Ignore unknown phase mismatch interrupts (caused by EOP interrupt) */
-				if (basr & BASR_PHASE_MATCH)
-					dprintk(NDEBUG_INTR, "scsi%d: unknown interrupt, "
-					       "BASR 0x%x, MR 0x%x, SR 0x%x\n",
-					       HOSTNO, basr, NCR5380_read(MODE_REG),
-					       NCR5380_read(STATUS_REG));
-				(void)NCR5380_read(RESET_PARITY_INTERRUPT_REG);
+		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);
+
+			dprintk(NDEBUG_INTR, "scsi%d: interrupt with SEL and IO\n",
+			        HOSTNO);
+
+			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);
+
+			dprintk(NDEBUG_INTR, "scsi%d: unknown interrupt\n", HOSTNO);
 #ifdef SUN3_SCSI_VME
-				dregs->csr |= CSR_DMA_ENABLE;
+			dregs->csr |= CSR_DMA_ENABLE;
 #endif
-			}
-		} /* if !(SELECTION || PARITY) */
+		}
 		handled = 1;
-	} /* BASR & IRQ */ else {
-		printk(KERN_NOTICE "scsi%d: interrupt without IRQ bit set in BASR, "
-		       "BASR 0x%X, MR 0x%X, SR 0x%x\n", HOSTNO, basr,
-		       NCR5380_read(MODE_REG), NCR5380_read(STATUS_REG));
-		(void)NCR5380_read(RESET_PARITY_INTERRUPT_REG);
+	} else {
+		shost_printk(KERN_NOTICE, instance, "interrupt without IRQ bit\n");
 #ifdef SUN3_SCSI_VME
 		dregs->csr |= CSR_DMA_ENABLE;
 #endif
 	}
 
-	if (!done)
-		queue_work(hostdata->work_q, &hostdata->main_task);
-
 	return IRQ_RETVAL(handled);
 }
 
@@ -1503,9 +1507,10 @@ static int NCR5380_select(struct Scsi_Ho
 	if ((NCR5380_read(STATUS_REG) & (SR_SEL | SR_IO)) == (SR_SEL | SR_IO)) {
 		NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
 		NCR5380_reselect(instance);
+		if (!hostdata->connected)
+			NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
 		printk(KERN_ERR "scsi%d: reselection after won arbitration?\n",
 		       HOSTNO);
-		NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
 		return -1;
 	}
 
@@ -1865,19 +1870,14 @@ static int NCR5380_transfer_dma(struct S
 	/* 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(TARGET_COMMAND_REG, 1);
-		NCR5380_read(RESET_PARITY_INTERRUPT_REG);
 		NCR5380_write(INITIATOR_COMMAND_REG, 0);
-		NCR5380_write(MODE_REG,
-			      (NCR5380_read(MODE_REG) | MR_DMA_MODE | MR_ENABLE_EOP_INTR));
 		NCR5380_write(START_DMA_INITIATOR_RECEIVE_REG, 0);
 	} else {
-		NCR5380_write(TARGET_COMMAND_REG, 0);
-		NCR5380_read(RESET_PARITY_INTERRUPT_REG);
 		NCR5380_write(INITIATOR_COMMAND_REG, ICR_ASSERT_DATA);
-		NCR5380_write(MODE_REG,
-			      (NCR5380_read(MODE_REG) | MR_DMA_MODE | MR_ENABLE_EOP_INTR));
 		NCR5380_write(START_DMA_SEND_REG, 0);
 	}
 
@@ -1906,10 +1906,8 @@ static int NCR5380_transfer_dma(struct S
 		   c, (p & SR_IO) ? "to" : "from", d);
 
 	NCR5380_write(TARGET_COMMAND_REG, PHASE_SR_TO_TCR(p));
-
-#ifdef REAL_DMA
-	NCR5380_write(MODE_REG, MR_BASE | MR_DMA_MODE | MR_ENABLE_EOP_INTR | MR_MONITOR_BSY);
-#endif /* def REAL_DMA  */
+	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
@@ -2383,10 +2381,10 @@ static void NCR5380_information_transfer
 #endif
 					hostdata->connected = NULL;
 					cmd->result = DID_ERROR << 16;
-					NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
 					maybe_release_dma_irq(instance);
 					local_irq_restore(flags);
 					cmd->scsi_done(cmd);
+					NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
 					return;
 				}
 				msgout = NOP;
Index: linux/drivers/scsi/dtc.c
===================================================================
--- linux.orig/drivers/scsi/dtc.c	2015-11-18 19:33:52.000000000 +1100
+++ linux/drivers/scsi/dtc.c	2015-11-18 19:33:53.000000000 +1100
@@ -334,8 +334,6 @@ static inline int NCR5380_pread(struct S
 	struct NCR5380_hostdata *hostdata = shost_priv(instance);
 
 	i = 0;
-	NCR5380_read(RESET_PARITY_INTERRUPT_REG);
-	NCR5380_write(MODE_REG, MR_ENABLE_EOP_INTR | MR_DMA_MODE);
 	if (instance->irq == NO_IRQ)
 		NCR5380_write(DTC_CONTROL_REG, CSR_DIR_READ);
 	else
@@ -357,9 +355,7 @@ static inline int NCR5380_pread(struct S
 	rtrc(4);
 	while (!(NCR5380_read(DTC_CONTROL_REG) & D_CR_ACCESS))
 		++i;
-	NCR5380_write(MODE_REG, 0);	/* Clear the operating mode */
 	rtrc(0);
-	NCR5380_read(RESET_PARITY_INTERRUPT_REG);
 	if (i > hostdata->spin_max_r)
 		hostdata->spin_max_r = i;
 	return (0);
@@ -383,9 +379,6 @@ static inline int NCR5380_pwrite(struct
 	int i;
 	struct NCR5380_hostdata *hostdata = shost_priv(instance);
 
-	NCR5380_read(RESET_PARITY_INTERRUPT_REG);
-	NCR5380_write(MODE_REG, MR_ENABLE_EOP_INTR | MR_DMA_MODE);
-	/* set direction (write) */
 	if (instance->irq == NO_IRQ)
 		NCR5380_write(DTC_CONTROL_REG, 0);
 	else
@@ -410,7 +403,6 @@ static inline int NCR5380_pwrite(struct
 		++i;
 	rtrc(7);
 	/* Check for parity error here. fixme. */
-	NCR5380_write(MODE_REG, 0);	/* Clear the operating mode */
 	rtrc(0);
 	if (i > hostdata->spin_max_w)
 		hostdata->spin_max_w = i;
Index: linux/drivers/scsi/g_NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/g_NCR5380.c	2015-11-18 19:33:38.000000000 +1100
+++ linux/drivers/scsi/g_NCR5380.c	2015-11-18 19:33:53.000000000 +1100
@@ -596,8 +596,6 @@ static inline int NCR5380_pread(struct S
 	if (!(NCR5380_read(BUS_AND_STATUS_REG) & BASR_END_DMA_TRANSFER))
 		printk(KERN_ERR "53C400r: no end dma signal\n");
 		
-	NCR5380_write(MODE_REG, MR_BASE);
-	NCR5380_read(RESET_PARITY_INTERRUPT_REG);
 	return 0;
 }
 

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

* [PATCH 40/71] ncr5380: Introduce NCR5380_poll_politely2
  2015-11-18  8:34 ` Finn Thain
@ 2015-11-18  8:35   ` Finn Thain
  -1 siblings, 0 replies; 268+ messages in thread
From: Finn Thain @ 2015-11-18  8:35 UTC (permalink / raw)
  To: James E.J. Bottomley, Michael Schmitz, linux-m68k, linux-scsi,
	linux-kernel

[-- Attachment #1: ncr5380-poll_politely2 --]
[-- Type: text/plain, Size: 9185 bytes --]

SCSI bus protocol sometimes requires monitoring two related conditions
simultaneously. Enhance NCR5380_poll_politely() for this purpose, and
put it to use in the arbitration algorithm. It will also find use in
pseudo DMA.

Signed-off-by: Finn Thain <fthain@telegraphics.com.au>

---
 drivers/scsi/NCR5380.c       |   68 +++++++++++++++++++++++++------------------
 drivers/scsi/atari_NCR5380.c |   64 ++++++++++++++++++++++++----------------
 2 files changed, 79 insertions(+), 53 deletions(-)

Index: linux/drivers/scsi/atari_NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/atari_NCR5380.c	2015-11-18 19:33:53.000000000 +1100
+++ linux/drivers/scsi/atari_NCR5380.c	2015-11-18 19:33:55.000000000 +1100
@@ -457,11 +457,14 @@ static inline void initialize_SCp(struct
 }
 
 /**
- * NCR5380_poll_politely - wait for chip register value
+ * NCR5380_poll_politely2 - wait for two chip register values
  * @instance: controller to poll
- * @reg: 5380 register to poll
- * @bit: Bitmask to check
- * @val: Value required to exit
+ * @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
@@ -469,11 +472,12 @@ static inline void initialize_SCp(struct
  * (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 event occurred otherwise -ETIMEDOUT.
+ * Returns 0 if either or both event(s) occurred otherwise -ETIMEDOUT.
  */
 
-static int NCR5380_poll_politely(struct Scsi_Host *instance,
-                                 int reg, int bit, int val, int wait)
+static int NCR5380_poll_politely2(struct Scsi_Host *instance,
+                                  int reg1, int bit1, int val1,
+                                  int reg2, int bit2, int val2, int wait)
 {
 	unsigned long start = jiffies;
 	unsigned long n;
@@ -481,7 +485,9 @@ static int NCR5380_poll_politely(struct
 	/* Busy-wait for up to 1 jiffy */
 	n = loops_per_jiffy;
 	do {
-		if ((NCR5380_read(reg) & bit) == val)
+		if ((NCR5380_read(reg1) & bit1) == val1)
+			return 0;
+		if ((NCR5380_read(reg2) & bit2) == val2)
 			return 0;
 		cpu_relax();
 	} while (--n > 0);
@@ -493,7 +499,9 @@ static int NCR5380_poll_politely(struct
 	n = min(20000U, jiffies_to_usecs(wait));
 	do {
 		udelay(1);
-		if ((NCR5380_read(reg) & bit) == val)
+		if ((NCR5380_read(reg1) & bit1) == val1)
+			return 0;
+		if ((NCR5380_read(reg2) & bit2) == val2)
 			return 0;
 		cpu_relax();
 	} while (--n > 0);
@@ -504,13 +512,22 @@ static int NCR5380_poll_politely(struct
 	/* Repeatedly sleep for 1 ms until deadline */
 	while (time_is_after_jiffies(start + wait)) {
 		schedule_timeout_uninterruptible(1);
-		if ((NCR5380_read(reg) & bit) == val)
+		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);
+}
+
 #include <linux/delay.h>
 
 #if NDEBUG
@@ -1342,7 +1359,6 @@ static int NCR5380_select(struct Scsi_Ho
 	int len;
 	int err;
 	unsigned long flags;
-	unsigned long timeout;
 
 	NCR5380_dprint(NDEBUG_ARBITRATION, instance);
 	dprintk(NDEBUG_ARBITRATION, "scsi%d: starting arbitration, id = %d\n", HOSTNO,
@@ -1372,20 +1388,18 @@ static int NCR5380_select(struct Scsi_Ho
 	 */
 
 	local_irq_restore(flags);
-	timeout = jiffies + HZ;
-	while (1) {
-		if (time_is_before_jiffies(timeout)) {
-			NCR5380_write(MODE_REG, MR_BASE);
-			shost_printk(KERN_ERR, instance,
-			             "select: arbitration timeout\n");
-			return -1;
-		}
-		if (!(NCR5380_read(MODE_REG) & MR_ARBITRATE)) {
-			/* Reselection interrupt */
-			return -1;
-		}
-		if (NCR5380_read(INITIATOR_COMMAND_REG) & ICR_ARBITRATION_PROGRESS)
-			break;
+	err = NCR5380_poll_politely2(instance, MODE_REG, MR_ARBITRATE, 0,
+	                INITIATOR_COMMAND_REG, ICR_ARBITRATION_PROGRESS,
+	                                       ICR_ARBITRATION_PROGRESS, HZ);
+	if (!(NCR5380_read(MODE_REG) & MR_ARBITRATE)) {
+		/* Reselection interrupt */
+		return -1;
+	}
+	if (err < 0) {
+		NCR5380_write(MODE_REG, MR_BASE);
+		shost_printk(KERN_ERR, instance,
+		             "select: arbitration timeout\n");
+		return -1;
 	}
 
 	/* The SCSI-2 arbitration delay is 2.4 us */
Index: linux/drivers/scsi/NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/NCR5380.c	2015-11-18 19:33:53.000000000 +1100
+++ linux/drivers/scsi/NCR5380.c	2015-11-18 19:33:55.000000000 +1100
@@ -262,11 +262,14 @@ static inline void initialize_SCp(struct
 }
 
 /**
- * NCR5380_poll_politely - wait for chip register value
+ * NCR5380_poll_politely2 - wait for two chip register values
  * @instance: controller to poll
- * @reg: 5380 register to poll
- * @bit: Bitmask to check
- * @val: Value required to exit
+ * @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
@@ -274,11 +277,12 @@ static inline void initialize_SCp(struct
  * (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 event occurred otherwise -ETIMEDOUT.
+ * Returns 0 if either or both event(s) occurred otherwise -ETIMEDOUT.
  */
 
-static int NCR5380_poll_politely(struct Scsi_Host *instance,
-                                 int reg, int bit, int val, int wait)
+static int NCR5380_poll_politely2(struct Scsi_Host *instance,
+                                  int reg1, int bit1, int val1,
+                                  int reg2, int bit2, int val2, int wait)
 {
 	unsigned long start = jiffies;
 	unsigned long n;
@@ -286,7 +290,9 @@ static int NCR5380_poll_politely(struct
 	/* Busy-wait for up to 1 jiffy */
 	n = loops_per_jiffy;
 	do {
-		if ((NCR5380_read(reg) & bit) == val)
+		if ((NCR5380_read(reg1) & bit1) == val1)
+			return 0;
+		if ((NCR5380_read(reg2) & bit2) == val2)
 			return 0;
 		cpu_relax();
 	} while (--n > 0);
@@ -298,7 +304,9 @@ static int NCR5380_poll_politely(struct
 	n = min(20000U, jiffies_to_usecs(wait));
 	do {
 		udelay(1);
-		if ((NCR5380_read(reg) & bit) == val)
+		if ((NCR5380_read(reg1) & bit1) == val1)
+			return 0;
+		if ((NCR5380_read(reg2) & bit2) == val2)
 			return 0;
 		cpu_relax();
 	} while (--n > 0);
@@ -309,13 +317,22 @@ static int NCR5380_poll_politely(struct
 	/* Repeatedly sleep for 1 ms until deadline */
 	while (time_is_after_jiffies(start + wait)) {
 		schedule_timeout_uninterruptible(1);
-		if ((NCR5380_read(reg) & bit) == val)
+		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);
+}
+
 static struct {
 	unsigned char value;
 	const char *name;
@@ -1094,7 +1111,6 @@ static int NCR5380_select(struct Scsi_Ho
 	unsigned char *data;
 	int len;
 	int err;
-	unsigned long timeout;
 
 	NCR5380_dprint(NDEBUG_ARBITRATION, instance);
 	dprintk(NDEBUG_ARBITRATION, "scsi%d : starting arbitration, id = %d\n", instance->host_no, instance->this_id);
@@ -1118,23 +1134,19 @@ static int NCR5380_select(struct Scsi_Ho
 	 */
 
 	spin_unlock_irq(instance->host_lock);
-	timeout = jiffies + HZ;
-	while (1) {
-		if (time_is_before_jiffies(timeout)) {
-			NCR5380_write(MODE_REG, MR_BASE);
-			shost_printk(KERN_ERR, instance,
-			             "select: arbitration timeout\n");
-			spin_lock_irq(instance->host_lock);
-			return -1;
-		}
-		spin_lock_irq(instance->host_lock);
-		if (!(NCR5380_read(MODE_REG) & MR_ARBITRATE)) {
-			/* Reselection interrupt */
-			return -1;
-		}
-		if (NCR5380_read(INITIATOR_COMMAND_REG) & ICR_ARBITRATION_PROGRESS)
-			break;
-		spin_unlock_irq(instance->host_lock);
+	err = NCR5380_poll_politely2(instance, MODE_REG, MR_ARBITRATE, 0,
+	                INITIATOR_COMMAND_REG, ICR_ARBITRATION_PROGRESS,
+	                                       ICR_ARBITRATION_PROGRESS, HZ);
+	spin_lock_irq(instance->host_lock);
+	if (!(NCR5380_read(MODE_REG) & MR_ARBITRATE)) {
+		/* Reselection interrupt */
+		return -1;
+	}
+	if (err < 0) {
+		NCR5380_write(MODE_REG, MR_BASE);
+		shost_printk(KERN_ERR, instance,
+		             "select: arbitration timeout\n");
+		return -1;
 	}
 
 	/* The SCSI-2 arbitration delay is 2.4 us */



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

* [PATCH 40/71] ncr5380: Introduce NCR5380_poll_politely2
@ 2015-11-18  8:35   ` Finn Thain
  0 siblings, 0 replies; 268+ messages in thread
From: Finn Thain @ 2015-11-18  8:35 UTC (permalink / raw)
  To: James E.J. Bottomley, Michael Schmitz, linux-m68k, linux-scsi,
	linux-kernel

[-- Attachment #1: ncr5380-poll_politely2 --]
[-- Type: text/plain, Size: 9183 bytes --]

SCSI bus protocol sometimes requires monitoring two related conditions
simultaneously. Enhance NCR5380_poll_politely() for this purpose, and
put it to use in the arbitration algorithm. It will also find use in
pseudo DMA.

Signed-off-by: Finn Thain <fthain@telegraphics.com.au>

---
 drivers/scsi/NCR5380.c       |   68 +++++++++++++++++++++++++------------------
 drivers/scsi/atari_NCR5380.c |   64 ++++++++++++++++++++++++----------------
 2 files changed, 79 insertions(+), 53 deletions(-)

Index: linux/drivers/scsi/atari_NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/atari_NCR5380.c	2015-11-18 19:33:53.000000000 +1100
+++ linux/drivers/scsi/atari_NCR5380.c	2015-11-18 19:33:55.000000000 +1100
@@ -457,11 +457,14 @@ static inline void initialize_SCp(struct
 }
 
 /**
- * NCR5380_poll_politely - wait for chip register value
+ * NCR5380_poll_politely2 - wait for two chip register values
  * @instance: controller to poll
- * @reg: 5380 register to poll
- * @bit: Bitmask to check
- * @val: Value required to exit
+ * @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
@@ -469,11 +472,12 @@ static inline void initialize_SCp(struct
  * (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 event occurred otherwise -ETIMEDOUT.
+ * Returns 0 if either or both event(s) occurred otherwise -ETIMEDOUT.
  */
 
-static int NCR5380_poll_politely(struct Scsi_Host *instance,
-                                 int reg, int bit, int val, int wait)
+static int NCR5380_poll_politely2(struct Scsi_Host *instance,
+                                  int reg1, int bit1, int val1,
+                                  int reg2, int bit2, int val2, int wait)
 {
 	unsigned long start = jiffies;
 	unsigned long n;
@@ -481,7 +485,9 @@ static int NCR5380_poll_politely(struct
 	/* Busy-wait for up to 1 jiffy */
 	n = loops_per_jiffy;
 	do {
-		if ((NCR5380_read(reg) & bit) == val)
+		if ((NCR5380_read(reg1) & bit1) == val1)
+			return 0;
+		if ((NCR5380_read(reg2) & bit2) == val2)
 			return 0;
 		cpu_relax();
 	} while (--n > 0);
@@ -493,7 +499,9 @@ static int NCR5380_poll_politely(struct
 	n = min(20000U, jiffies_to_usecs(wait));
 	do {
 		udelay(1);
-		if ((NCR5380_read(reg) & bit) == val)
+		if ((NCR5380_read(reg1) & bit1) == val1)
+			return 0;
+		if ((NCR5380_read(reg2) & bit2) == val2)
 			return 0;
 		cpu_relax();
 	} while (--n > 0);
@@ -504,13 +512,22 @@ static int NCR5380_poll_politely(struct
 	/* Repeatedly sleep for 1 ms until deadline */
 	while (time_is_after_jiffies(start + wait)) {
 		schedule_timeout_uninterruptible(1);
-		if ((NCR5380_read(reg) & bit) == val)
+		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);
+}
+
 #include <linux/delay.h>
 
 #if NDEBUG
@@ -1342,7 +1359,6 @@ static int NCR5380_select(struct Scsi_Ho
 	int len;
 	int err;
 	unsigned long flags;
-	unsigned long timeout;
 
 	NCR5380_dprint(NDEBUG_ARBITRATION, instance);
 	dprintk(NDEBUG_ARBITRATION, "scsi%d: starting arbitration, id = %d\n", HOSTNO,
@@ -1372,20 +1388,18 @@ static int NCR5380_select(struct Scsi_Ho
 	 */
 
 	local_irq_restore(flags);
-	timeout = jiffies + HZ;
-	while (1) {
-		if (time_is_before_jiffies(timeout)) {
-			NCR5380_write(MODE_REG, MR_BASE);
-			shost_printk(KERN_ERR, instance,
-			             "select: arbitration timeout\n");
-			return -1;
-		}
-		if (!(NCR5380_read(MODE_REG) & MR_ARBITRATE)) {
-			/* Reselection interrupt */
-			return -1;
-		}
-		if (NCR5380_read(INITIATOR_COMMAND_REG) & ICR_ARBITRATION_PROGRESS)
-			break;
+	err = NCR5380_poll_politely2(instance, MODE_REG, MR_ARBITRATE, 0,
+	                INITIATOR_COMMAND_REG, ICR_ARBITRATION_PROGRESS,
+	                                       ICR_ARBITRATION_PROGRESS, HZ);
+	if (!(NCR5380_read(MODE_REG) & MR_ARBITRATE)) {
+		/* Reselection interrupt */
+		return -1;
+	}
+	if (err < 0) {
+		NCR5380_write(MODE_REG, MR_BASE);
+		shost_printk(KERN_ERR, instance,
+		             "select: arbitration timeout\n");
+		return -1;
 	}
 
 	/* The SCSI-2 arbitration delay is 2.4 us */
Index: linux/drivers/scsi/NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/NCR5380.c	2015-11-18 19:33:53.000000000 +1100
+++ linux/drivers/scsi/NCR5380.c	2015-11-18 19:33:55.000000000 +1100
@@ -262,11 +262,14 @@ static inline void initialize_SCp(struct
 }
 
 /**
- * NCR5380_poll_politely - wait for chip register value
+ * NCR5380_poll_politely2 - wait for two chip register values
  * @instance: controller to poll
- * @reg: 5380 register to poll
- * @bit: Bitmask to check
- * @val: Value required to exit
+ * @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
@@ -274,11 +277,12 @@ static inline void initialize_SCp(struct
  * (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 event occurred otherwise -ETIMEDOUT.
+ * Returns 0 if either or both event(s) occurred otherwise -ETIMEDOUT.
  */
 
-static int NCR5380_poll_politely(struct Scsi_Host *instance,
-                                 int reg, int bit, int val, int wait)
+static int NCR5380_poll_politely2(struct Scsi_Host *instance,
+                                  int reg1, int bit1, int val1,
+                                  int reg2, int bit2, int val2, int wait)
 {
 	unsigned long start = jiffies;
 	unsigned long n;
@@ -286,7 +290,9 @@ static int NCR5380_poll_politely(struct
 	/* Busy-wait for up to 1 jiffy */
 	n = loops_per_jiffy;
 	do {
-		if ((NCR5380_read(reg) & bit) == val)
+		if ((NCR5380_read(reg1) & bit1) == val1)
+			return 0;
+		if ((NCR5380_read(reg2) & bit2) == val2)
 			return 0;
 		cpu_relax();
 	} while (--n > 0);
@@ -298,7 +304,9 @@ static int NCR5380_poll_politely(struct
 	n = min(20000U, jiffies_to_usecs(wait));
 	do {
 		udelay(1);
-		if ((NCR5380_read(reg) & bit) == val)
+		if ((NCR5380_read(reg1) & bit1) == val1)
+			return 0;
+		if ((NCR5380_read(reg2) & bit2) == val2)
 			return 0;
 		cpu_relax();
 	} while (--n > 0);
@@ -309,13 +317,22 @@ static int NCR5380_poll_politely(struct
 	/* Repeatedly sleep for 1 ms until deadline */
 	while (time_is_after_jiffies(start + wait)) {
 		schedule_timeout_uninterruptible(1);
-		if ((NCR5380_read(reg) & bit) == val)
+		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);
+}
+
 static struct {
 	unsigned char value;
 	const char *name;
@@ -1094,7 +1111,6 @@ static int NCR5380_select(struct Scsi_Ho
 	unsigned char *data;
 	int len;
 	int err;
-	unsigned long timeout;
 
 	NCR5380_dprint(NDEBUG_ARBITRATION, instance);
 	dprintk(NDEBUG_ARBITRATION, "scsi%d : starting arbitration, id = %d\n", instance->host_no, instance->this_id);
@@ -1118,23 +1134,19 @@ static int NCR5380_select(struct Scsi_Ho
 	 */
 
 	spin_unlock_irq(instance->host_lock);
-	timeout = jiffies + HZ;
-	while (1) {
-		if (time_is_before_jiffies(timeout)) {
-			NCR5380_write(MODE_REG, MR_BASE);
-			shost_printk(KERN_ERR, instance,
-			             "select: arbitration timeout\n");
-			spin_lock_irq(instance->host_lock);
-			return -1;
-		}
-		spin_lock_irq(instance->host_lock);
-		if (!(NCR5380_read(MODE_REG) & MR_ARBITRATE)) {
-			/* Reselection interrupt */
-			return -1;
-		}
-		if (NCR5380_read(INITIATOR_COMMAND_REG) & ICR_ARBITRATION_PROGRESS)
-			break;
-		spin_unlock_irq(instance->host_lock);
+	err = NCR5380_poll_politely2(instance, MODE_REG, MR_ARBITRATE, 0,
+	                INITIATOR_COMMAND_REG, ICR_ARBITRATION_PROGRESS,
+	                                       ICR_ARBITRATION_PROGRESS, HZ);
+	spin_lock_irq(instance->host_lock);
+	if (!(NCR5380_read(MODE_REG) & MR_ARBITRATE)) {
+		/* Reselection interrupt */
+		return -1;
+	}
+	if (err < 0) {
+		NCR5380_write(MODE_REG, MR_BASE);
+		shost_printk(KERN_ERR, instance,
+		             "select: arbitration timeout\n");
+		return -1;
 	}
 
 	/* The SCSI-2 arbitration delay is 2.4 us */

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

* [PATCH 41/71] ncr5380: Replace redundant flags with FLAG_NO_DMA_FIXUP
  2015-11-18  8:34 ` Finn Thain
@ 2015-11-18  8:35   ` Finn Thain
  -1 siblings, 0 replies; 268+ messages in thread
From: Finn Thain @ 2015-11-18  8:35 UTC (permalink / raw)
  To: James E.J. Bottomley, Michael Schmitz, linux-m68k, linux-scsi,
	linux-kernel

[-- Attachment #1: ncr5380-remove-FLAG_NCR53C400 --]
[-- Type: text/plain, Size: 7679 bytes --]

The flags DMA_WORKS_RIGHT, FLAG_NCR53C400 and FLAG_HAS_LAST_BYTE_SENT
all mean the same thing, i.e. the chip is not a 538[01]. (More recent
devices such as the 53C80 have a 'Last Byte Sent' bit in the Target
Command Register as well as other fixes for End-of-DMA errata.)

These flags have no additional meanings since previous cleanup patches
eliminated the NCR53C400 macro, moved g_NCR5380-specific code out of the
core driver and standardized interrupt handling.

Use the FLAG_NO_DMA_FIXUP flag to suppress End-of-DMA errata workarounds,
for those cards and drivers that make use of the TCR_LAST_BYTE_SENT bit.
Remove the old flags.

Signed-off-by: Finn Thain <fthain@telegraphics.com.au>

---
 drivers/scsi/NCR5380.c   |   68 +++++++++++++++--------------------------------
 drivers/scsi/NCR5380.h   |    4 --
 drivers/scsi/dtc.c       |    4 --
 drivers/scsi/g_NCR5380.c |    5 +--
 4 files changed, 26 insertions(+), 55 deletions(-)

Index: linux/drivers/scsi/NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/NCR5380.c	2015-11-18 19:33:55.000000000 +1100
+++ linux/drivers/scsi/NCR5380.c	2015-11-18 19:33:56.000000000 +1100
@@ -552,7 +552,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_NCR53C400     ? "NCR53C400 "     : "",
+	         hostdata->flags & FLAG_NO_DMA_FIXUP  ? "NO_DMA_FIXUP "  : "",
 	         hostdata->flags & FLAG_DTC3181E      ? "DTC3181E "      : "",
 	         hostdata->flags & FLAG_NO_PSEUDO_DMA ? "NO_PSEUDO_DMA " : "",
 	         hostdata->flags & FLAG_TOSHIBA_DELAY ? "TOSHIBA_DELAY "  : "",
@@ -712,6 +712,7 @@ static int NCR5380_init(struct Scsi_Host
 	hostdata->connected = NULL;
 	hostdata->issue_queue = NULL;
 	hostdata->disconnected_queue = NULL;
+	hostdata->flags = flags;
 	
 	INIT_WORK(&hostdata->main_task, NCR5380_main);
 	hostdata->work_q = alloc_workqueue("ncr5380_%d",
@@ -720,12 +721,6 @@ static int NCR5380_init(struct Scsi_Host
 	if (!hostdata->work_q)
 		return -ENOMEM;
 
-	/* The CHECK code seems to break the 53C400. Will check it later maybe */
-	if (flags & FLAG_NCR53C400)
-		hostdata->flags = FLAG_HAS_LAST_BYTE_SENT | flags;
-	else
-		hostdata->flags = FLAG_CHECK_LAST_BYTE_SENT | flags;
-
 	hostdata->host = instance;
 
 	prepare_info(instance);
@@ -1609,7 +1604,7 @@ static int NCR5380_transfer_dma(struct S
 	 * before the setting of DMA mode to after transfer of the last byte.
 	 */
 
-	if (hostdata->flags & FLAG_NCR53C400)
+	if (hostdata->flags & FLAG_NO_DMA_FIXUP)
 		NCR5380_write(MODE_REG, MR_BASE | MR_DMA_MODE | MR_MONITOR_BSY |
 		                        MR_ENABLE_EOP_INTR);
 	else
@@ -1729,14 +1724,9 @@ static int NCR5380_transfer_dma(struct S
 	return 0;
 #else				/* defined(REAL_DMA_POLL) */
 	if (p & SR_IO) {
-#ifdef DMA_WORKS_RIGHT
-		foo = NCR5380_pread(instance, d, c);
-#else
-		int diff = 1;
-		if (hostdata->flags & FLAG_NCR53C400) {
-			diff = 0;
-		}
-		if (!(foo = NCR5380_pread(instance, d, c - diff))) {
+		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
@@ -1759,46 +1749,32 @@ static int NCR5380_transfer_dma(struct S
 			 * byte.
 			 */
 
-			if (!(hostdata->flags & FLAG_NCR53C400)) {
-				while (!(NCR5380_read(BUS_AND_STATUS_REG) & BASR_DRQ));
-				/* Wait for clean handshake */
-				while (NCR5380_read(STATUS_REG) & SR_REQ);
-				d[c - 1] = NCR5380_read(INPUT_DATA_REG);
+			if (NCR5380_poll_politely(instance, BUS_AND_STATUS_REG,
+			                          BASR_DRQ, BASR_DRQ, HZ) < 0) {
+				foo = -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;
+				shost_printk(KERN_ERR, instance, "PDMA read: !REQ timeout\n");
 			}
+			d[c - 1] = NCR5380_read(INPUT_DATA_REG);
 		}
-#endif
 	} else {
-#ifdef DMA_WORKS_RIGHT
 		foo = NCR5380_pwrite(instance, d, c);
-#else
-		int timeout;
-		dprintk(NDEBUG_C400_PWRITE, "About to pwrite %d bytes\n", c);
-		if (!(foo = NCR5380_pwrite(instance, d, c))) {
+		if (!foo && !(hostdata->flags & FLAG_NO_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.  
 			 */
-			if (!(hostdata->flags & FLAG_HAS_LAST_BYTE_SENT)) {
-				timeout = 20000;
-				while (!(NCR5380_read(BUS_AND_STATUS_REG) & BASR_DRQ) && (NCR5380_read(BUS_AND_STATUS_REG) & BASR_PHASE_MATCH));
-
-				if (!timeout)
-					dprintk(NDEBUG_LAST_BYTE_SENT, "scsi%d : timed out on last byte\n", instance->host_no);
-
-				if (hostdata->flags & FLAG_CHECK_LAST_BYTE_SENT) {
-					hostdata->flags &= ~FLAG_CHECK_LAST_BYTE_SENT;
-					if (NCR5380_read(TARGET_COMMAND_REG) & TCR_LAST_BYTE_SENT) {
-						hostdata->flags |= FLAG_HAS_LAST_BYTE_SENT;
-						dprintk(NDEBUG_LAST_BYTE_SENT, "scsi%d : last byte sent works\n", instance->host_no);
-					}
-				}
-			} else {
-				dprintk(NDEBUG_C400_PWRITE, "Waiting for LASTBYTE\n");
-				while (!(NCR5380_read(TARGET_COMMAND_REG) & TCR_LAST_BYTE_SENT));
-				dprintk(NDEBUG_C400_PWRITE, "Got LASTBYTE\n");
+			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;
+				shost_printk(KERN_ERR, instance, "PDMA write: DRQ and phase timeout\n");
 			}
 		}
-#endif
 	}
 	NCR5380_write(MODE_REG, MR_BASE);
 	NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
Index: linux/drivers/scsi/NCR5380.h
===================================================================
--- linux.orig/drivers/scsi/NCR5380.h	2015-11-18 19:33:51.000000000 +1100
+++ linux/drivers/scsi/NCR5380.h	2015-11-18 19:33:56.000000000 +1100
@@ -226,9 +226,7 @@
 #define NO_IRQ		0
 #endif
 
-#define FLAG_HAS_LAST_BYTE_SENT		1	/* NCR53c81 or better */
-#define FLAG_CHECK_LAST_BYTE_SENT	2	/* Only test once */
-#define FLAG_NCR53C400			4	/* NCR53c400 */
+#define FLAG_NO_DMA_FIXUP		1	/* No DMA errata workarounds */
 #define FLAG_NO_PSEUDO_DMA		8	/* Inhibit DMA */
 #define FLAG_DTC3181E			16	/* DTC3181E */
 #define FLAG_LATE_DMA_SETUP		32	/* Setup NCR before DMA H/W */
Index: linux/drivers/scsi/dtc.c
===================================================================
--- linux.orig/drivers/scsi/dtc.c	2015-11-18 19:33:53.000000000 +1100
+++ linux/drivers/scsi/dtc.c	2015-11-18 19:33:56.000000000 +1100
@@ -1,7 +1,5 @@
 #define PSEUDO_DMA
 #define DONT_USE_INTR
-#define DMA_WORKS_RIGHT
-
 
 /*
  * DTC 3180/3280 driver, by
@@ -233,7 +231,7 @@ found:
 		instance->base = addr;
 		((struct NCR5380_hostdata *)(instance)->hostdata)->base = base;
 
-		if (NCR5380_init(instance, 0))
+		if (NCR5380_init(instance, FLAG_NO_DMA_FIXUP))
 			goto out_unregister;
 
 		NCR5380_maybe_reset_bus(instance);
Index: linux/drivers/scsi/g_NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/g_NCR5380.c	2015-11-18 19:33:53.000000000 +1100
+++ linux/drivers/scsi/g_NCR5380.c	2015-11-18 19:33:56.000000000 +1100
@@ -320,9 +320,8 @@ static int __init generic_NCR5380_detect
 			flags = FLAG_NO_PSEUDO_DMA;
 			break;
 		case BOARD_NCR53C400:
-#ifdef PSEUDO_DMA
-			flags = FLAG_NCR53C400;
-#else
+			flags = FLAG_NO_DMA_FIXUP;
+#ifndef PSEUDO_DMA
 			flags = FLAG_NO_PSEUDO_DMA;
 #endif
 			break;



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

* [PATCH 41/71] ncr5380: Replace redundant flags with FLAG_NO_DMA_FIXUP
@ 2015-11-18  8:35   ` Finn Thain
  0 siblings, 0 replies; 268+ messages in thread
From: Finn Thain @ 2015-11-18  8:35 UTC (permalink / raw)
  To: James E.J. Bottomley, Michael Schmitz, linux-m68k, linux-scsi,
	linux-kernel

[-- Attachment #1: ncr5380-remove-FLAG_NCR53C400 --]
[-- Type: text/plain, Size: 7677 bytes --]

The flags DMA_WORKS_RIGHT, FLAG_NCR53C400 and FLAG_HAS_LAST_BYTE_SENT
all mean the same thing, i.e. the chip is not a 538[01]. (More recent
devices such as the 53C80 have a 'Last Byte Sent' bit in the Target
Command Register as well as other fixes for End-of-DMA errata.)

These flags have no additional meanings since previous cleanup patches
eliminated the NCR53C400 macro, moved g_NCR5380-specific code out of the
core driver and standardized interrupt handling.

Use the FLAG_NO_DMA_FIXUP flag to suppress End-of-DMA errata workarounds,
for those cards and drivers that make use of the TCR_LAST_BYTE_SENT bit.
Remove the old flags.

Signed-off-by: Finn Thain <fthain@telegraphics.com.au>

---
 drivers/scsi/NCR5380.c   |   68 +++++++++++++++--------------------------------
 drivers/scsi/NCR5380.h   |    4 --
 drivers/scsi/dtc.c       |    4 --
 drivers/scsi/g_NCR5380.c |    5 +--
 4 files changed, 26 insertions(+), 55 deletions(-)

Index: linux/drivers/scsi/NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/NCR5380.c	2015-11-18 19:33:55.000000000 +1100
+++ linux/drivers/scsi/NCR5380.c	2015-11-18 19:33:56.000000000 +1100
@@ -552,7 +552,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_NCR53C400     ? "NCR53C400 "     : "",
+	         hostdata->flags & FLAG_NO_DMA_FIXUP  ? "NO_DMA_FIXUP "  : "",
 	         hostdata->flags & FLAG_DTC3181E      ? "DTC3181E "      : "",
 	         hostdata->flags & FLAG_NO_PSEUDO_DMA ? "NO_PSEUDO_DMA " : "",
 	         hostdata->flags & FLAG_TOSHIBA_DELAY ? "TOSHIBA_DELAY "  : "",
@@ -712,6 +712,7 @@ static int NCR5380_init(struct Scsi_Host
 	hostdata->connected = NULL;
 	hostdata->issue_queue = NULL;
 	hostdata->disconnected_queue = NULL;
+	hostdata->flags = flags;
 	
 	INIT_WORK(&hostdata->main_task, NCR5380_main);
 	hostdata->work_q = alloc_workqueue("ncr5380_%d",
@@ -720,12 +721,6 @@ static int NCR5380_init(struct Scsi_Host
 	if (!hostdata->work_q)
 		return -ENOMEM;
 
-	/* The CHECK code seems to break the 53C400. Will check it later maybe */
-	if (flags & FLAG_NCR53C400)
-		hostdata->flags = FLAG_HAS_LAST_BYTE_SENT | flags;
-	else
-		hostdata->flags = FLAG_CHECK_LAST_BYTE_SENT | flags;
-
 	hostdata->host = instance;
 
 	prepare_info(instance);
@@ -1609,7 +1604,7 @@ static int NCR5380_transfer_dma(struct S
 	 * before the setting of DMA mode to after transfer of the last byte.
 	 */
 
-	if (hostdata->flags & FLAG_NCR53C400)
+	if (hostdata->flags & FLAG_NO_DMA_FIXUP)
 		NCR5380_write(MODE_REG, MR_BASE | MR_DMA_MODE | MR_MONITOR_BSY |
 		                        MR_ENABLE_EOP_INTR);
 	else
@@ -1729,14 +1724,9 @@ static int NCR5380_transfer_dma(struct S
 	return 0;
 #else				/* defined(REAL_DMA_POLL) */
 	if (p & SR_IO) {
-#ifdef DMA_WORKS_RIGHT
-		foo = NCR5380_pread(instance, d, c);
-#else
-		int diff = 1;
-		if (hostdata->flags & FLAG_NCR53C400) {
-			diff = 0;
-		}
-		if (!(foo = NCR5380_pread(instance, d, c - diff))) {
+		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
@@ -1759,46 +1749,32 @@ static int NCR5380_transfer_dma(struct S
 			 * byte.
 			 */
 
-			if (!(hostdata->flags & FLAG_NCR53C400)) {
-				while (!(NCR5380_read(BUS_AND_STATUS_REG) & BASR_DRQ));
-				/* Wait for clean handshake */
-				while (NCR5380_read(STATUS_REG) & SR_REQ);
-				d[c - 1] = NCR5380_read(INPUT_DATA_REG);
+			if (NCR5380_poll_politely(instance, BUS_AND_STATUS_REG,
+			                          BASR_DRQ, BASR_DRQ, HZ) < 0) {
+				foo = -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;
+				shost_printk(KERN_ERR, instance, "PDMA read: !REQ timeout\n");
 			}
+			d[c - 1] = NCR5380_read(INPUT_DATA_REG);
 		}
-#endif
 	} else {
-#ifdef DMA_WORKS_RIGHT
 		foo = NCR5380_pwrite(instance, d, c);
-#else
-		int timeout;
-		dprintk(NDEBUG_C400_PWRITE, "About to pwrite %d bytes\n", c);
-		if (!(foo = NCR5380_pwrite(instance, d, c))) {
+		if (!foo && !(hostdata->flags & FLAG_NO_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.  
 			 */
-			if (!(hostdata->flags & FLAG_HAS_LAST_BYTE_SENT)) {
-				timeout = 20000;
-				while (!(NCR5380_read(BUS_AND_STATUS_REG) & BASR_DRQ) && (NCR5380_read(BUS_AND_STATUS_REG) & BASR_PHASE_MATCH));
-
-				if (!timeout)
-					dprintk(NDEBUG_LAST_BYTE_SENT, "scsi%d : timed out on last byte\n", instance->host_no);
-
-				if (hostdata->flags & FLAG_CHECK_LAST_BYTE_SENT) {
-					hostdata->flags &= ~FLAG_CHECK_LAST_BYTE_SENT;
-					if (NCR5380_read(TARGET_COMMAND_REG) & TCR_LAST_BYTE_SENT) {
-						hostdata->flags |= FLAG_HAS_LAST_BYTE_SENT;
-						dprintk(NDEBUG_LAST_BYTE_SENT, "scsi%d : last byte sent works\n", instance->host_no);
-					}
-				}
-			} else {
-				dprintk(NDEBUG_C400_PWRITE, "Waiting for LASTBYTE\n");
-				while (!(NCR5380_read(TARGET_COMMAND_REG) & TCR_LAST_BYTE_SENT));
-				dprintk(NDEBUG_C400_PWRITE, "Got LASTBYTE\n");
+			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;
+				shost_printk(KERN_ERR, instance, "PDMA write: DRQ and phase timeout\n");
 			}
 		}
-#endif
 	}
 	NCR5380_write(MODE_REG, MR_BASE);
 	NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
Index: linux/drivers/scsi/NCR5380.h
===================================================================
--- linux.orig/drivers/scsi/NCR5380.h	2015-11-18 19:33:51.000000000 +1100
+++ linux/drivers/scsi/NCR5380.h	2015-11-18 19:33:56.000000000 +1100
@@ -226,9 +226,7 @@
 #define NO_IRQ		0
 #endif
 
-#define FLAG_HAS_LAST_BYTE_SENT		1	/* NCR53c81 or better */
-#define FLAG_CHECK_LAST_BYTE_SENT	2	/* Only test once */
-#define FLAG_NCR53C400			4	/* NCR53c400 */
+#define FLAG_NO_DMA_FIXUP		1	/* No DMA errata workarounds */
 #define FLAG_NO_PSEUDO_DMA		8	/* Inhibit DMA */
 #define FLAG_DTC3181E			16	/* DTC3181E */
 #define FLAG_LATE_DMA_SETUP		32	/* Setup NCR before DMA H/W */
Index: linux/drivers/scsi/dtc.c
===================================================================
--- linux.orig/drivers/scsi/dtc.c	2015-11-18 19:33:53.000000000 +1100
+++ linux/drivers/scsi/dtc.c	2015-11-18 19:33:56.000000000 +1100
@@ -1,7 +1,5 @@
 #define PSEUDO_DMA
 #define DONT_USE_INTR
-#define DMA_WORKS_RIGHT
-
 
 /*
  * DTC 3180/3280 driver, by
@@ -233,7 +231,7 @@ found:
 		instance->base = addr;
 		((struct NCR5380_hostdata *)(instance)->hostdata)->base = base;
 
-		if (NCR5380_init(instance, 0))
+		if (NCR5380_init(instance, FLAG_NO_DMA_FIXUP))
 			goto out_unregister;
 
 		NCR5380_maybe_reset_bus(instance);
Index: linux/drivers/scsi/g_NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/g_NCR5380.c	2015-11-18 19:33:53.000000000 +1100
+++ linux/drivers/scsi/g_NCR5380.c	2015-11-18 19:33:56.000000000 +1100
@@ -320,9 +320,8 @@ static int __init generic_NCR5380_detect
 			flags = FLAG_NO_PSEUDO_DMA;
 			break;
 		case BOARD_NCR53C400:
-#ifdef PSEUDO_DMA
-			flags = FLAG_NCR53C400;
-#else
+			flags = FLAG_NO_DMA_FIXUP;
+#ifndef PSEUDO_DMA
 			flags = FLAG_NO_PSEUDO_DMA;
 #endif
 			break;

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

* [PATCH 42/71] ncr5380: Replace READ_OVERRUNS macro with FLAG_NO_DMA_FIXUPS
  2015-11-18  8:34 ` Finn Thain
@ 2015-11-18  8:35   ` Finn Thain
  -1 siblings, 0 replies; 268+ messages in thread
From: Finn Thain @ 2015-11-18  8:35 UTC (permalink / raw)
  To: James E.J. Bottomley, Michael Schmitz, linux-m68k, linux-scsi,
	linux-kernel

[-- Attachment #1: ncr5380-remove-READ_OVERRUNS --]
[-- Type: text/plain, Size: 2986 bytes --]

The workarounds for chip errata appear twice, in slightly different
forms. One is used when defined(REAL_DMA) || defined(REAL_DMA_POLL), the
other when defined(PSEUDO_DMA). In the PDMA case, the workarounds have
been made conditional on FLAG_NO_DMA_FIXUPS. Do the same for the DMA case,
to eliminate the READ_OVERRUNS macro.

Signed-off-by: Finn Thain <fthain@telegraphics.com.au>

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

Index: linux/drivers/scsi/NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/NCR5380.c	2015-11-18 19:33:56.000000000 +1100
+++ linux/drivers/scsi/NCR5380.c	2015-11-18 19:33:58.000000000 +1100
@@ -94,11 +94,6 @@
 #undef REAL_DMA
 #endif
 
-#ifdef REAL_DMA_POLL
-#undef READ_OVERRUNS
-#define READ_OVERRUNS
-#endif
-
 #ifdef BOARD_REQUIRES_NO_DELAY
 #define io_recovery_delay(x)
 #else
@@ -1581,11 +1576,10 @@ static int NCR5380_transfer_dma(struct S
 		return -1;
 	}
 #if defined(REAL_DMA) || defined(REAL_DMA_POLL)
-#ifdef READ_OVERRUNS
 	if (p & SR_IO) {
-		c -= 2;
+		if (!(hostdata->flags & FLAG_NO_DMA_FIXUPS))
+			c -= 2;
 	}
-#endif
 	dprintk(NDEBUG_DMA, "scsi%d : initializing DMA channel %d for %s, %d bytes %s %0x\n", instance->host_no, instance->dma_channel, (p & SR_IO) ? "reading" : "writing", c, (p & SR_IO) ? "to" : "from", (unsigned) d);
 	hostdata->dma_len = (p & SR_IO) ? NCR5380_dma_read_setup(instance, d, c) : NCR5380_dma_write_setup(instance, d, c);
 #endif
@@ -1671,13 +1665,14 @@ static int NCR5380_transfer_dma(struct S
  */
 
 	if (p & SR_IO) {
-#ifdef READ_OVERRUNS
-		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;
+		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;
+			}
 		}
-#endif
 	} else {
 		int limit = 100;
 		while (((tmp = NCR5380_read(BUS_AND_STATUS_REG)) & BASR_ACK) || (NCR5380_read(STATUS_REG) & SR_REQ)) {
@@ -1699,8 +1694,8 @@ static int NCR5380_transfer_dma(struct S
 	*data += c;
 	*phase = NCR5380_read(STATUS_REG) & PHASE_MASK;
 
-#ifdef READ_OVERRUNS
-	if (*phase == p && (p & SR_IO) && residue == 0) {
+	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;
@@ -1715,7 +1710,6 @@ static int NCR5380_transfer_dma(struct S
 		NCR5380_transfer_pio(instance, phase, &cnt, data);
 		*count -= toPIO - cnt;
 	}
-#endif
 
 	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;



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

* [PATCH 42/71] ncr5380: Replace READ_OVERRUNS macro with FLAG_NO_DMA_FIXUPS
@ 2015-11-18  8:35   ` Finn Thain
  0 siblings, 0 replies; 268+ messages in thread
From: Finn Thain @ 2015-11-18  8:35 UTC (permalink / raw)
  To: James E.J. Bottomley, Michael Schmitz, linux-m68k, linux-scsi,
	linux-kernel

[-- Attachment #1: ncr5380-remove-READ_OVERRUNS --]
[-- Type: text/plain, Size: 2984 bytes --]

The workarounds for chip errata appear twice, in slightly different
forms. One is used when defined(REAL_DMA) || defined(REAL_DMA_POLL), the
other when defined(PSEUDO_DMA). In the PDMA case, the workarounds have
been made conditional on FLAG_NO_DMA_FIXUPS. Do the same for the DMA case,
to eliminate the READ_OVERRUNS macro.

Signed-off-by: Finn Thain <fthain@telegraphics.com.au>

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

Index: linux/drivers/scsi/NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/NCR5380.c	2015-11-18 19:33:56.000000000 +1100
+++ linux/drivers/scsi/NCR5380.c	2015-11-18 19:33:58.000000000 +1100
@@ -94,11 +94,6 @@
 #undef REAL_DMA
 #endif
 
-#ifdef REAL_DMA_POLL
-#undef READ_OVERRUNS
-#define READ_OVERRUNS
-#endif
-
 #ifdef BOARD_REQUIRES_NO_DELAY
 #define io_recovery_delay(x)
 #else
@@ -1581,11 +1576,10 @@ static int NCR5380_transfer_dma(struct S
 		return -1;
 	}
 #if defined(REAL_DMA) || defined(REAL_DMA_POLL)
-#ifdef READ_OVERRUNS
 	if (p & SR_IO) {
-		c -= 2;
+		if (!(hostdata->flags & FLAG_NO_DMA_FIXUPS))
+			c -= 2;
 	}
-#endif
 	dprintk(NDEBUG_DMA, "scsi%d : initializing DMA channel %d for %s, %d bytes %s %0x\n", instance->host_no, instance->dma_channel, (p & SR_IO) ? "reading" : "writing", c, (p & SR_IO) ? "to" : "from", (unsigned) d);
 	hostdata->dma_len = (p & SR_IO) ? NCR5380_dma_read_setup(instance, d, c) : NCR5380_dma_write_setup(instance, d, c);
 #endif
@@ -1671,13 +1665,14 @@ static int NCR5380_transfer_dma(struct S
  */
 
 	if (p & SR_IO) {
-#ifdef READ_OVERRUNS
-		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;
+		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;
+			}
 		}
-#endif
 	} else {
 		int limit = 100;
 		while (((tmp = NCR5380_read(BUS_AND_STATUS_REG)) & BASR_ACK) || (NCR5380_read(STATUS_REG) & SR_REQ)) {
@@ -1699,8 +1694,8 @@ static int NCR5380_transfer_dma(struct S
 	*data += c;
 	*phase = NCR5380_read(STATUS_REG) & PHASE_MASK;
 
-#ifdef READ_OVERRUNS
-	if (*phase == p && (p & SR_IO) && residue == 0) {
+	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;
@@ -1715,7 +1710,6 @@ static int NCR5380_transfer_dma(struct S
 		NCR5380_transfer_pio(instance, phase, &cnt, data);
 		*count -= toPIO - cnt;
 	}
-#endif
 
 	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;

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

* [PATCH 43/71] ncr5380: Standardize reselection handling
  2015-11-18  8:34 ` Finn Thain
@ 2015-11-18  8:35   ` Finn Thain
  -1 siblings, 0 replies; 268+ messages in thread
From: Finn Thain @ 2015-11-18  8:35 UTC (permalink / raw)
  To: James E.J. Bottomley, Michael Schmitz, linux-m68k, linux-scsi,
	linux-kernel

[-- Attachment #1: ncr5380-standardize-reselection-handling --]
[-- Type: text/plain, Size: 10577 bytes --]

Bring the two NCR5380_reselect() implementations into agreement.

Replace infinite loops in atari_NCR5380.c with timeouts, as per NCR5380.c.

Remove 'abort' flag in NCR5380.c as per atari_NCR5380.c -- if reselection
fails, there may be no MESSAGE IN phase so don't attempt data transfer.

During selection, don't interfere with the chip registers after a
reselection interrupt intervenes.

Clean up some trivial issues with code style, comments and printk.

Signed-off-by: Finn Thain <fthain@telegraphics.com.au>

---
 drivers/scsi/NCR5380.c       |  115 +++++++++++++++++++++++--------------------
 drivers/scsi/atari_NCR5380.c |   50 ++++++++++--------
 2 files changed, 93 insertions(+), 72 deletions(-)

Index: linux/drivers/scsi/NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/NCR5380.c	2015-11-18 19:33:58.000000000 +1100
+++ linux/drivers/scsi/NCR5380.c	2015-11-18 19:33:59.000000000 +1100
@@ -1177,6 +1177,10 @@ static int NCR5380_select(struct Scsi_Ho
 	else
 		udelay(2);
 
+	/* NCR5380_reselect() clears MODE_REG after a reselection interrupt */
+	if (!(NCR5380_read(MODE_REG) & MR_ARBITRATE))
+		return -1;
+
 	dprintk(NDEBUG_ARBITRATION, "scsi%d : won arbitration\n", instance->host_no);
 
 	/* 
@@ -1948,12 +1952,14 @@ static void NCR5380_information_transfer
 						cmd->scsi_done(cmd);
 					}
 
-					NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
 					/* 
 					 * 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);
 					return;
 				case MESSAGE_REJECT:
 					/* Accept message by clearing ACK */
@@ -2139,7 +2145,6 @@ static void NCR5380_reselect(struct Scsi
 	unsigned char msg[3];
 	unsigned char *data;
 	struct scsi_cmnd *tmp = NULL, *prev;
-	int abort = 0;
 
 	/*
 	 * Disable arbitration, etc. since the host adapter obviously
@@ -2149,7 +2154,7 @@ static void NCR5380_reselect(struct Scsi
 	NCR5380_write(MODE_REG, MR_BASE);
 
 	target_mask = NCR5380_read(CURRENT_SCSI_DATA_REG) & ~(hostdata->id_mask);
-	dprintk(NDEBUG_SELECTION, "scsi%d : reselect\n", instance->host_no);
+	dprintk(NDEBUG_RESELECTION, "scsi%d : reselect\n", instance->host_no);
 
 	/* 
 	 * At this point, we have detected that our SCSI ID is on the bus,
@@ -2161,77 +2166,85 @@ static void NCR5380_reselect(struct Scsi
 	 */
 
 	NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_BSY);
-
-	/* FIXME: timeout too long, must fail to workqueue */	
-	if(NCR5380_poll_politely(instance, STATUS_REG, SR_SEL, 0, 2*HZ)<0)
-		abort = 1;
-		
+	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.
-	 * FIXME: timeout needed and fail to work queeu
 	 */
 
 	if (NCR5380_poll_politely(instance,
-	                          STATUS_REG, SR_REQ, SR_REQ, 2 * HZ) < 0)
-		abort = 1;
+	                          STATUS_REG, SR_REQ, SR_REQ, 2 * HZ) < 0) {
+		do_abort(instance);
+		return;
+	}
 
 	len = 1;
 	data = msg;
 	phase = PHASE_MSGIN;
 	NCR5380_transfer_pio(instance, &phase, &len, &data);
 
+	if (len) {
+		do_abort(instance);
+		return;
+	}
+
 	if (!(msg[0] & 0x80)) {
-		printk(KERN_ERR "scsi%d : expecting IDENTIFY message, got ", instance->host_no);
+		shost_printk(KERN_ERR, instance, "expecting IDENTIFY message, got ");
 		spi_print_msg(msg);
-		abort = 1;
-	} else {
-		/* Accept message by clearing ACK */
-		NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
-		lun = (msg[0] & 0x07);
-
-		/* 
-		 * We need to add code for SCSI-II to track which devices have
-		 * I_T_L_Q nexuses established, and which have simple I_T_L
-		 * nexuses so we can chose to do additional data transfer.
-		 */
+		printk("\n");
+		do_abort(instance);
+		return;
+	}
+	lun = msg[0] & 0x07;
 
-		/* 
-		 * 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.
-		 */
+	/*
+	 * We need to add code for SCSI-II to track which devices have
+	 * I_T_L_Q nexuses established, and which have simple I_T_L
+	 * nexuses so we can chose to do additional data transfer.
+	 */
 
+	/*
+	 * 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.
+	 */
 
-		for (tmp = (struct scsi_cmnd *) hostdata->disconnected_queue, prev = NULL; tmp; prev = tmp, tmp = (struct scsi_cmnd *) tmp->host_scribble)
-			if ((target_mask == (1 << tmp->device->id)) && (lun == (u8)tmp->device->lun)
-			    ) {
-				if (prev) {
-					REMOVE(prev, prev->host_scribble, tmp, tmp->host_scribble);
-					prev->host_scribble = tmp->host_scribble;
-				} else {
-					REMOVE(-1, hostdata->disconnected_queue, tmp, tmp->host_scribble);
-					hostdata->disconnected_queue = (struct scsi_cmnd *) tmp->host_scribble;
-				}
-				tmp->host_scribble = NULL;
-				break;
+	for (tmp = (struct scsi_cmnd *) hostdata->disconnected_queue, prev = NULL;
+	     tmp; prev = tmp, tmp = (struct scsi_cmnd *) tmp->host_scribble) {
+		if ((target_mask == (1 << tmp->device->id)) && (lun == (u8)tmp->device->lun)) {
+			if (prev) {
+				REMOVE(prev, prev->host_scribble, tmp, tmp->host_scribble);
+				prev->host_scribble = tmp->host_scribble;
+			} else {
+				REMOVE(-1, hostdata->disconnected_queue, tmp, tmp->host_scribble);
+				hostdata->disconnected_queue =
+					(struct scsi_cmnd *) tmp->host_scribble;
 			}
-		if (!tmp) {
-			printk(KERN_ERR "scsi%d : warning : target bitmask %02x lun %d not in disconnect_queue.\n", instance->host_no, target_mask, lun);
-			/* 
-			 * Since we have an established nexus that we can't do anything with,
-			 * we must abort it.  
-			 */
-			abort = 1;
+			tmp->host_scribble = NULL;
+			break;
 		}
 	}
-
-	if (abort) {
+	if (!tmp) {
+		shost_printk(KERN_ERR, instance, "target bitmask 0x%02x lun %d not in disconnected queue.\n",
+		             target_mask, lun);
+		/*
+		 * Since we have an established nexus that we can't do anything with,
+		 * we must abort it.
+		 */
 		do_abort(instance);
-	} else {
-		hostdata->connected = tmp;
-		dprintk(NDEBUG_RESELECTION, "scsi%d : nexus established, target = %d, lun = %llu, tag = %d\n", instance->host_no, tmp->device->id, tmp->device->lun, tmp->tag);
+		return;
 	}
+
+	/* Accept message by clearing ACK */
+	NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
+
+	hostdata->connected = tmp;
+	dprintk(NDEBUG_RESELECTION, "scsi%d : nexus established, target = %d, lun = %llu, tag = %d\n",
+	        instance->host_no, tmp->device->id, tmp->device->lun, tmp->tag);
 }
 
 /*
Index: linux/drivers/scsi/atari_NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/atari_NCR5380.c	2015-11-18 19:33:55.000000000 +1100
+++ linux/drivers/scsi/atari_NCR5380.c	2015-11-18 19:33:59.000000000 +1100
@@ -1442,11 +1442,9 @@ static int NCR5380_select(struct Scsi_Ho
 	else
 		udelay(2);
 
-	if (hostdata->connected) {
-		NCR5380_write(MODE_REG, MR_BASE);
-		NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
+	/* NCR5380_reselect() clears MODE_REG after a reselection interrupt */
+	if (!(NCR5380_read(MODE_REG) & MR_ARBITRATE))
 		return -1;
-	}
 
 	dprintk(NDEBUG_ARBITRATION, "scsi%d: won arbitration\n", HOSTNO);
 
@@ -2219,13 +2217,15 @@ static void NCR5380_information_transfer
 						cmd->scsi_done(cmd);
 					}
 
-					NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
 					/*
 					 * 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);
+
 					/* ++roman: For Falcon SCSI, release the lock on the
 					 * ST-DMA here if no other commands are waiting on the
 					 * disconnected queue.
@@ -2478,17 +2478,22 @@ static void NCR5380_reselect(struct Scsi
 	 */
 
 	NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_BSY);
-
-	while (NCR5380_read(STATUS_REG) & SR_SEL)
-		;
+	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.
 	 */
 
-	while (!(NCR5380_read(STATUS_REG) & SR_REQ))
-		;
+	if (NCR5380_poll_politely(instance,
+	                          STATUS_REG, SR_REQ, SR_REQ, 2 * HZ) < 0) {
+		do_abort(instance);
+		return;
+	}
 
 #if defined(CONFIG_SUN3) && defined(REAL_DMA)
 	/* acknowledge toggle to MSGIN */
@@ -2501,15 +2506,21 @@ static void NCR5380_reselect(struct Scsi
 	data = msg;
 	phase = PHASE_MSGIN;
 	NCR5380_transfer_pio(instance, &phase, &len, &data);
+
+	if (len) {
+		do_abort(instance);
+		return;
+	}
 #endif
 
 	if (!(msg[0] & 0x80)) {
-		printk(KERN_DEBUG "scsi%d: expecting IDENTIFY message, got ", HOSTNO);
+		shost_printk(KERN_ERR, instance, "expecting IDENTIFY message, got ");
 		spi_print_msg(msg);
+		printk("\n");
 		do_abort(instance);
 		return;
 	}
-	lun = (msg[0] & 0x07);
+	lun = msg[0] & 0x07;
 
 #if defined(SUPPORT_TAGS) && !defined(CONFIG_SUN3)
 	/* If the phase is still MSGIN, the target wants to send some more
@@ -2537,7 +2548,7 @@ static void NCR5380_reselect(struct Scsi
 
 	for (tmp = (struct scsi_cmnd *) hostdata->disconnected_queue, prev = NULL;
 	     tmp; prev = tmp, tmp = NEXT(tmp)) {
-		if ((target_mask == (1 << tmp->device->id)) && (lun == tmp->device->lun)
+		if ((target_mask == (1 << tmp->device->id)) && (lun == (u8)tmp->device->lun)
 #ifdef SUPPORT_TAGS
 		    && (tag == tmp->tag)
 #endif
@@ -2555,16 +2566,13 @@ static void NCR5380_reselect(struct Scsi
 	}
 
 	if (!tmp) {
-		printk(KERN_WARNING "scsi%d: warning: target bitmask %02x lun %d "
 #ifdef SUPPORT_TAGS
-		       "tag %d "
-#endif
-		       "not in disconnected_queue.\n",
-		       HOSTNO, target_mask, lun
-#ifdef SUPPORT_TAGS
-		       , tag
+		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.



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

* [PATCH 43/71] ncr5380: Standardize reselection handling
@ 2015-11-18  8:35   ` Finn Thain
  0 siblings, 0 replies; 268+ messages in thread
From: Finn Thain @ 2015-11-18  8:35 UTC (permalink / raw)
  To: James E.J. Bottomley, Michael Schmitz, linux-m68k, linux-scsi,
	linux-kernel

[-- Attachment #1: ncr5380-standardize-reselection-handling --]
[-- Type: text/plain, Size: 10575 bytes --]

Bring the two NCR5380_reselect() implementations into agreement.

Replace infinite loops in atari_NCR5380.c with timeouts, as per NCR5380.c.

Remove 'abort' flag in NCR5380.c as per atari_NCR5380.c -- if reselection
fails, there may be no MESSAGE IN phase so don't attempt data transfer.

During selection, don't interfere with the chip registers after a
reselection interrupt intervenes.

Clean up some trivial issues with code style, comments and printk.

Signed-off-by: Finn Thain <fthain@telegraphics.com.au>

---
 drivers/scsi/NCR5380.c       |  115 +++++++++++++++++++++++--------------------
 drivers/scsi/atari_NCR5380.c |   50 ++++++++++--------
 2 files changed, 93 insertions(+), 72 deletions(-)

Index: linux/drivers/scsi/NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/NCR5380.c	2015-11-18 19:33:58.000000000 +1100
+++ linux/drivers/scsi/NCR5380.c	2015-11-18 19:33:59.000000000 +1100
@@ -1177,6 +1177,10 @@ static int NCR5380_select(struct Scsi_Ho
 	else
 		udelay(2);
 
+	/* NCR5380_reselect() clears MODE_REG after a reselection interrupt */
+	if (!(NCR5380_read(MODE_REG) & MR_ARBITRATE))
+		return -1;
+
 	dprintk(NDEBUG_ARBITRATION, "scsi%d : won arbitration\n", instance->host_no);
 
 	/* 
@@ -1948,12 +1952,14 @@ static void NCR5380_information_transfer
 						cmd->scsi_done(cmd);
 					}
 
-					NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
 					/* 
 					 * 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);
 					return;
 				case MESSAGE_REJECT:
 					/* Accept message by clearing ACK */
@@ -2139,7 +2145,6 @@ static void NCR5380_reselect(struct Scsi
 	unsigned char msg[3];
 	unsigned char *data;
 	struct scsi_cmnd *tmp = NULL, *prev;
-	int abort = 0;
 
 	/*
 	 * Disable arbitration, etc. since the host adapter obviously
@@ -2149,7 +2154,7 @@ static void NCR5380_reselect(struct Scsi
 	NCR5380_write(MODE_REG, MR_BASE);
 
 	target_mask = NCR5380_read(CURRENT_SCSI_DATA_REG) & ~(hostdata->id_mask);
-	dprintk(NDEBUG_SELECTION, "scsi%d : reselect\n", instance->host_no);
+	dprintk(NDEBUG_RESELECTION, "scsi%d : reselect\n", instance->host_no);
 
 	/* 
 	 * At this point, we have detected that our SCSI ID is on the bus,
@@ -2161,77 +2166,85 @@ static void NCR5380_reselect(struct Scsi
 	 */
 
 	NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_BSY);
-
-	/* FIXME: timeout too long, must fail to workqueue */	
-	if(NCR5380_poll_politely(instance, STATUS_REG, SR_SEL, 0, 2*HZ)<0)
-		abort = 1;
-		
+	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.
-	 * FIXME: timeout needed and fail to work queeu
 	 */
 
 	if (NCR5380_poll_politely(instance,
-	                          STATUS_REG, SR_REQ, SR_REQ, 2 * HZ) < 0)
-		abort = 1;
+	                          STATUS_REG, SR_REQ, SR_REQ, 2 * HZ) < 0) {
+		do_abort(instance);
+		return;
+	}
 
 	len = 1;
 	data = msg;
 	phase = PHASE_MSGIN;
 	NCR5380_transfer_pio(instance, &phase, &len, &data);
 
+	if (len) {
+		do_abort(instance);
+		return;
+	}
+
 	if (!(msg[0] & 0x80)) {
-		printk(KERN_ERR "scsi%d : expecting IDENTIFY message, got ", instance->host_no);
+		shost_printk(KERN_ERR, instance, "expecting IDENTIFY message, got ");
 		spi_print_msg(msg);
-		abort = 1;
-	} else {
-		/* Accept message by clearing ACK */
-		NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
-		lun = (msg[0] & 0x07);
-
-		/* 
-		 * We need to add code for SCSI-II to track which devices have
-		 * I_T_L_Q nexuses established, and which have simple I_T_L
-		 * nexuses so we can chose to do additional data transfer.
-		 */
+		printk("\n");
+		do_abort(instance);
+		return;
+	}
+	lun = msg[0] & 0x07;
 
-		/* 
-		 * 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.
-		 */
+	/*
+	 * We need to add code for SCSI-II to track which devices have
+	 * I_T_L_Q nexuses established, and which have simple I_T_L
+	 * nexuses so we can chose to do additional data transfer.
+	 */
 
+	/*
+	 * 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.
+	 */
 
-		for (tmp = (struct scsi_cmnd *) hostdata->disconnected_queue, prev = NULL; tmp; prev = tmp, tmp = (struct scsi_cmnd *) tmp->host_scribble)
-			if ((target_mask == (1 << tmp->device->id)) && (lun == (u8)tmp->device->lun)
-			    ) {
-				if (prev) {
-					REMOVE(prev, prev->host_scribble, tmp, tmp->host_scribble);
-					prev->host_scribble = tmp->host_scribble;
-				} else {
-					REMOVE(-1, hostdata->disconnected_queue, tmp, tmp->host_scribble);
-					hostdata->disconnected_queue = (struct scsi_cmnd *) tmp->host_scribble;
-				}
-				tmp->host_scribble = NULL;
-				break;
+	for (tmp = (struct scsi_cmnd *) hostdata->disconnected_queue, prev = NULL;
+	     tmp; prev = tmp, tmp = (struct scsi_cmnd *) tmp->host_scribble) {
+		if ((target_mask == (1 << tmp->device->id)) && (lun == (u8)tmp->device->lun)) {
+			if (prev) {
+				REMOVE(prev, prev->host_scribble, tmp, tmp->host_scribble);
+				prev->host_scribble = tmp->host_scribble;
+			} else {
+				REMOVE(-1, hostdata->disconnected_queue, tmp, tmp->host_scribble);
+				hostdata->disconnected_queue =
+					(struct scsi_cmnd *) tmp->host_scribble;
 			}
-		if (!tmp) {
-			printk(KERN_ERR "scsi%d : warning : target bitmask %02x lun %d not in disconnect_queue.\n", instance->host_no, target_mask, lun);
-			/* 
-			 * Since we have an established nexus that we can't do anything with,
-			 * we must abort it.  
-			 */
-			abort = 1;
+			tmp->host_scribble = NULL;
+			break;
 		}
 	}
-
-	if (abort) {
+	if (!tmp) {
+		shost_printk(KERN_ERR, instance, "target bitmask 0x%02x lun %d not in disconnected queue.\n",
+		             target_mask, lun);
+		/*
+		 * Since we have an established nexus that we can't do anything with,
+		 * we must abort it.
+		 */
 		do_abort(instance);
-	} else {
-		hostdata->connected = tmp;
-		dprintk(NDEBUG_RESELECTION, "scsi%d : nexus established, target = %d, lun = %llu, tag = %d\n", instance->host_no, tmp->device->id, tmp->device->lun, tmp->tag);
+		return;
 	}
+
+	/* Accept message by clearing ACK */
+	NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
+
+	hostdata->connected = tmp;
+	dprintk(NDEBUG_RESELECTION, "scsi%d : nexus established, target = %d, lun = %llu, tag = %d\n",
+	        instance->host_no, tmp->device->id, tmp->device->lun, tmp->tag);
 }
 
 /*
Index: linux/drivers/scsi/atari_NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/atari_NCR5380.c	2015-11-18 19:33:55.000000000 +1100
+++ linux/drivers/scsi/atari_NCR5380.c	2015-11-18 19:33:59.000000000 +1100
@@ -1442,11 +1442,9 @@ static int NCR5380_select(struct Scsi_Ho
 	else
 		udelay(2);
 
-	if (hostdata->connected) {
-		NCR5380_write(MODE_REG, MR_BASE);
-		NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
+	/* NCR5380_reselect() clears MODE_REG after a reselection interrupt */
+	if (!(NCR5380_read(MODE_REG) & MR_ARBITRATE))
 		return -1;
-	}
 
 	dprintk(NDEBUG_ARBITRATION, "scsi%d: won arbitration\n", HOSTNO);
 
@@ -2219,13 +2217,15 @@ static void NCR5380_information_transfer
 						cmd->scsi_done(cmd);
 					}
 
-					NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
 					/*
 					 * 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);
+
 					/* ++roman: For Falcon SCSI, release the lock on the
 					 * ST-DMA here if no other commands are waiting on the
 					 * disconnected queue.
@@ -2478,17 +2478,22 @@ static void NCR5380_reselect(struct Scsi
 	 */
 
 	NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_BSY);
-
-	while (NCR5380_read(STATUS_REG) & SR_SEL)
-		;
+	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.
 	 */
 
-	while (!(NCR5380_read(STATUS_REG) & SR_REQ))
-		;
+	if (NCR5380_poll_politely(instance,
+	                          STATUS_REG, SR_REQ, SR_REQ, 2 * HZ) < 0) {
+		do_abort(instance);
+		return;
+	}
 
 #if defined(CONFIG_SUN3) && defined(REAL_DMA)
 	/* acknowledge toggle to MSGIN */
@@ -2501,15 +2506,21 @@ static void NCR5380_reselect(struct Scsi
 	data = msg;
 	phase = PHASE_MSGIN;
 	NCR5380_transfer_pio(instance, &phase, &len, &data);
+
+	if (len) {
+		do_abort(instance);
+		return;
+	}
 #endif
 
 	if (!(msg[0] & 0x80)) {
-		printk(KERN_DEBUG "scsi%d: expecting IDENTIFY message, got ", HOSTNO);
+		shost_printk(KERN_ERR, instance, "expecting IDENTIFY message, got ");
 		spi_print_msg(msg);
+		printk("\n");
 		do_abort(instance);
 		return;
 	}
-	lun = (msg[0] & 0x07);
+	lun = msg[0] & 0x07;
 
 #if defined(SUPPORT_TAGS) && !defined(CONFIG_SUN3)
 	/* If the phase is still MSGIN, the target wants to send some more
@@ -2537,7 +2548,7 @@ static void NCR5380_reselect(struct Scsi
 
 	for (tmp = (struct scsi_cmnd *) hostdata->disconnected_queue, prev = NULL;
 	     tmp; prev = tmp, tmp = NEXT(tmp)) {
-		if ((target_mask == (1 << tmp->device->id)) && (lun == tmp->device->lun)
+		if ((target_mask == (1 << tmp->device->id)) && (lun == (u8)tmp->device->lun)
 #ifdef SUPPORT_TAGS
 		    && (tag == tmp->tag)
 #endif
@@ -2555,16 +2566,13 @@ static void NCR5380_reselect(struct Scsi
 	}
 
 	if (!tmp) {
-		printk(KERN_WARNING "scsi%d: warning: target bitmask %02x lun %d "
 #ifdef SUPPORT_TAGS
-		       "tag %d "
-#endif
-		       "not in disconnected_queue.\n",
-		       HOSTNO, target_mask, lun
-#ifdef SUPPORT_TAGS
-		       , tag
+		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.

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

* [PATCH 44/71] ncr5380: Fix off-by-one bug in extended_msg[] bounds check
  2015-11-18  8:34 ` Finn Thain
@ 2015-11-18  8:35   ` Finn Thain
  -1 siblings, 0 replies; 268+ messages in thread
From: Finn Thain @ 2015-11-18  8:35 UTC (permalink / raw)
  To: James E.J. Bottomley, Michael Schmitz, linux-m68k, linux-scsi,
	linux-kernel

[-- Attachment #1: ncr5380-extended-message-length --]
[-- Type: text/plain, Size: 1799 bytes --]

Fix the array bounds check when transferring an extended message from the
target.

Signed-off-by: Finn Thain <fthain@telegraphics.com.au>

---
 drivers/scsi/NCR5380.c       |    3 ++-
 drivers/scsi/atari_NCR5380.c |    4 ++--
 2 files changed, 4 insertions(+), 3 deletions(-)

Index: linux/drivers/scsi/NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/NCR5380.c	2015-11-18 19:33:59.000000000 +1100
+++ linux/drivers/scsi/NCR5380.c	2015-11-18 19:34:00.000000000 +1100
@@ -2034,7 +2034,8 @@ static void NCR5380_information_transfer
 
 					dprintk(NDEBUG_EXTENDED, "scsi%d : length=%d, code=0x%02x\n", instance->host_no, (int) extended_msg[1], (int) extended_msg[2]);
 
-					if (!len && extended_msg[1] <= (sizeof(extended_msg) - 1)) {
+					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;
Index: linux/drivers/scsi/atari_NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/atari_NCR5380.c	2015-11-18 19:33:59.000000000 +1100
+++ linux/drivers/scsi/atari_NCR5380.c	2015-11-18 19:34:00.000000000 +1100
@@ -2326,8 +2326,8 @@ static void NCR5380_information_transfer
 					dprintk(NDEBUG_EXTENDED, "scsi%d: length=%d, code=0x%02x\n", HOSTNO,
 						   (int)extended_msg[1], (int)extended_msg[2]);
 
-					if (!len && extended_msg[1] <=
-					    (sizeof(extended_msg) - 1)) {
+					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;



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

* [PATCH 44/71] ncr5380: Fix off-by-one bug in extended_msg[] bounds check
@ 2015-11-18  8:35   ` Finn Thain
  0 siblings, 0 replies; 268+ messages in thread
From: Finn Thain @ 2015-11-18  8:35 UTC (permalink / raw)
  To: James E.J. Bottomley, Michael Schmitz, linux-m68k, linux-scsi,
	linux-kernel

[-- Attachment #1: ncr5380-extended-message-length --]
[-- Type: text/plain, Size: 1797 bytes --]

Fix the array bounds check when transferring an extended message from the
target.

Signed-off-by: Finn Thain <fthain@telegraphics.com.au>

---
 drivers/scsi/NCR5380.c       |    3 ++-
 drivers/scsi/atari_NCR5380.c |    4 ++--
 2 files changed, 4 insertions(+), 3 deletions(-)

Index: linux/drivers/scsi/NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/NCR5380.c	2015-11-18 19:33:59.000000000 +1100
+++ linux/drivers/scsi/NCR5380.c	2015-11-18 19:34:00.000000000 +1100
@@ -2034,7 +2034,8 @@ static void NCR5380_information_transfer
 
 					dprintk(NDEBUG_EXTENDED, "scsi%d : length=%d, code=0x%02x\n", instance->host_no, (int) extended_msg[1], (int) extended_msg[2]);
 
-					if (!len && extended_msg[1] <= (sizeof(extended_msg) - 1)) {
+					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;
Index: linux/drivers/scsi/atari_NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/atari_NCR5380.c	2015-11-18 19:33:59.000000000 +1100
+++ linux/drivers/scsi/atari_NCR5380.c	2015-11-18 19:34:00.000000000 +1100
@@ -2326,8 +2326,8 @@ static void NCR5380_information_transfer
 					dprintk(NDEBUG_EXTENDED, "scsi%d: length=%d, code=0x%02x\n", HOSTNO,
 						   (int)extended_msg[1], (int)extended_msg[2]);
 
-					if (!len && extended_msg[1] <=
-					    (sizeof(extended_msg) - 1)) {
+					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;

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

* [PATCH 45/71] ncr5380: Cleanup #include directives
  2015-11-18  8:34 ` Finn Thain
  (?)
@ 2015-11-18  8:35   ` Finn Thain
  -1 siblings, 0 replies; 268+ messages in thread
From: Finn Thain @ 2015-11-18  8:35 UTC (permalink / raw)
  To: James E.J. Bottomley, Michael Schmitz, linux-m68k, linux-scsi,
	linux-kernel, Russell King, linux-arm-kernel

[-- Attachment #1: ncr5380-move-core-driver-includes --]
[-- Type: text/plain, Size: 7522 bytes --]

Remove unused includes (stat.h, signal.h, proc_fs.h) and move includes
needed by the core drivers into the common header (delay.h etc).

Signed-off-by: Finn Thain <fthain@telegraphics.com.au>

---
 drivers/scsi/NCR5380.c       |    2 --
 drivers/scsi/NCR5380.h       |    4 ++++
 drivers/scsi/arm/cumana_1.c  |    4 ----
 drivers/scsi/arm/oak.c       |    2 --
 drivers/scsi/atari_NCR5380.c |    5 -----
 drivers/scsi/atari_scsi.c    |    1 -
 drivers/scsi/dmx3191d.c      |    5 -----
 drivers/scsi/dtc.c           |    4 +---
 drivers/scsi/g_NCR5380.c     |    6 ++----
 drivers/scsi/mac_scsi.c      |    1 -
 drivers/scsi/pas16.c         |    4 ----
 drivers/scsi/t128.c          |    3 ---
 12 files changed, 7 insertions(+), 34 deletions(-)

Index: linux/drivers/scsi/NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/NCR5380.c	2015-11-18 19:34:00.000000000 +1100
+++ linux/drivers/scsi/NCR5380.c	2015-11-18 19:34:01.000000000 +1100
@@ -79,8 +79,6 @@
  * 4.  Test SCSI-II tagged queueing (I have no devices which support 
  *      tagged queueing)
  */
-#include <scsi/scsi_dbg.h>
-#include <scsi/scsi_transport_spi.h>
 
 #if (NDEBUG & NDEBUG_LISTS)
 #define LIST(x,y) {printk("LINE:%d   Adding %p to %p\n", __LINE__, (void*)(x), (void*)(y)); if ((x)==(y)) udelay(5); }
Index: linux/drivers/scsi/NCR5380.h
===================================================================
--- linux.orig/drivers/scsi/NCR5380.h	2015-11-18 19:33:56.000000000 +1100
+++ linux/drivers/scsi/NCR5380.h	2015-11-18 19:34:01.000000000 +1100
@@ -22,8 +22,12 @@
 #ifndef NCR5380_H
 #define NCR5380_H
 
+#include <linux/delay.h>
 #include <linux/interrupt.h>
+#include <linux/workqueue.h>
+#include <scsi/scsi_dbg.h>
 #include <scsi/scsi_eh.h>
+#include <scsi/scsi_transport_spi.h>
 
 #define NDEBUG_ARBITRATION	0x1
 #define NDEBUG_AUTOSENSE	0x2
Index: linux/drivers/scsi/arm/cumana_1.c
===================================================================
--- linux.orig/drivers/scsi/arm/cumana_1.c	2015-11-18 19:33:35.000000000 +1100
+++ linux/drivers/scsi/arm/cumana_1.c	2015-11-18 19:34:01.000000000 +1100
@@ -4,9 +4,7 @@
  * Copyright 1995-2002, Russell King
  */
 #include <linux/module.h>
-#include <linux/signal.h>
 #include <linux/ioport.h>
-#include <linux/delay.h>
 #include <linux/blkdev.h>
 #include <linux/init.h>
 
@@ -15,8 +13,6 @@
 
 #include <scsi/scsi_host.h>
 
-#include <scsi/scsicam.h>
-
 #define PSEUDO_DMA
 
 #define priv(host)			((struct NCR5380_hostdata *)(host)->hostdata)
Index: linux/drivers/scsi/arm/oak.c
===================================================================
--- linux.orig/drivers/scsi/arm/oak.c	2015-11-18 19:33:35.000000000 +1100
+++ linux/drivers/scsi/arm/oak.c	2015-11-18 19:34:01.000000000 +1100
@@ -5,9 +5,7 @@
  */
 
 #include <linux/module.h>
-#include <linux/signal.h>
 #include <linux/ioport.h>
-#include <linux/delay.h>
 #include <linux/blkdev.h>
 #include <linux/init.h>
 
Index: linux/drivers/scsi/atari_NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/atari_NCR5380.c	2015-11-18 19:34:00.000000000 +1100
+++ linux/drivers/scsi/atari_NCR5380.c	2015-11-18 19:34:01.000000000 +1100
@@ -68,9 +68,6 @@
 
 /* Adapted for the sun3 by Sam Creasey. */
 
-#include <scsi/scsi_dbg.h>
-#include <scsi/scsi_transport_spi.h>
-
 #if (NDEBUG & NDEBUG_LISTS)
 #define LIST(x, y)						\
 	do {							\
@@ -528,8 +525,6 @@ static inline int NCR5380_poll_politely(
 	                                        reg, bit, val, wait);
 }
 
-#include <linux/delay.h>
-
 #if NDEBUG
 static struct {
 	unsigned char mask;
Index: linux/drivers/scsi/atari_scsi.c
===================================================================
--- linux.orig/drivers/scsi/atari_scsi.c	2015-11-18 19:33:27.000000000 +1100
+++ linux/drivers/scsi/atari_scsi.c	2015-11-18 19:34:01.000000000 +1100
@@ -66,7 +66,6 @@
 
 #include <linux/module.h>
 #include <linux/types.h>
-#include <linux/delay.h>
 #include <linux/blkdev.h>
 #include <linux/interrupt.h>
 #include <linux/init.h>
Index: linux/drivers/scsi/dmx3191d.c
===================================================================
--- linux.orig/drivers/scsi/dmx3191d.c	2015-11-18 19:33:27.000000000 +1100
+++ linux/drivers/scsi/dmx3191d.c	2015-11-18 19:34:01.000000000 +1100
@@ -41,11 +41,6 @@
 
 #define NCR5380_implementation_fields	/* none */
 
-/*
- * Includes needed for NCR5380.[ch] (XXX: Move them to NCR5380.h)
- */
-#include <linux/delay.h>
-
 #include "NCR5380.h"
 #include "NCR5380.c"
 
Index: linux/drivers/scsi/dtc.c
===================================================================
--- linux.orig/drivers/scsi/dtc.c	2015-11-18 19:33:56.000000000 +1100
+++ linux/drivers/scsi/dtc.c	2015-11-18 19:34:01.000000000 +1100
@@ -46,15 +46,13 @@
 
 
 #include <linux/module.h>
-#include <linux/signal.h>
 #include <linux/blkdev.h>
-#include <linux/delay.h>
-#include <linux/stat.h>
 #include <linux/string.h>
 #include <linux/init.h>
 #include <linux/interrupt.h>
 #include <linux/io.h>
 #include <scsi/scsi_host.h>
+
 #include "dtc.h"
 #define AUTOPROBE_IRQ
 #include "NCR5380.h"
Index: linux/drivers/scsi/g_NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/g_NCR5380.c	2015-11-18 19:33:56.000000000 +1100
+++ linux/drivers/scsi/g_NCR5380.c	2015-11-18 19:34:01.000000000 +1100
@@ -63,16 +63,14 @@
 #endif
 
 #include <asm/io.h>
-#include <linux/signal.h>
 #include <linux/blkdev.h>
+#include <linux/module.h>
 #include <scsi/scsi_host.h>
 #include "g_NCR5380.h"
 #include "NCR5380.h"
-#include <linux/stat.h>
 #include <linux/init.h>
 #include <linux/ioport.h>
 #include <linux/isapnp.h>
-#include <linux/delay.h>
 #include <linux/interrupt.h>
 
 static int ncr_irq;
@@ -733,7 +731,7 @@ static struct scsi_host_template driver_
 	.cmd_per_lun    	= CMD_PER_LUN,
         .use_clustering		= DISABLE_CLUSTERING,
 };
-#include <linux/module.h>
+
 #include "scsi_module.c"
 
 module_param(ncr_irq, int, 0);
Index: linux/drivers/scsi/mac_scsi.c
===================================================================
--- linux.orig/drivers/scsi/mac_scsi.c	2015-11-18 19:33:35.000000000 +1100
+++ linux/drivers/scsi/mac_scsi.c	2015-11-18 19:34:01.000000000 +1100
@@ -12,7 +12,6 @@
  */
 
 #include <linux/types.h>
-#include <linux/delay.h>
 #include <linux/module.h>
 #include <linux/ioport.h>
 #include <linux/init.h>
Index: linux/drivers/scsi/pas16.c
===================================================================
--- linux.orig/drivers/scsi/pas16.c	2015-11-18 19:33:52.000000000 +1100
+++ linux/drivers/scsi/pas16.c	2015-11-18 19:34:01.000000000 +1100
@@ -69,14 +69,10 @@
  
 #include <linux/module.h>
 
-#include <linux/signal.h>
-#include <linux/proc_fs.h>
 #include <asm/io.h>
 #include <asm/dma.h>
 #include <linux/blkdev.h>
-#include <linux/delay.h>
 #include <linux/interrupt.h>
-#include <linux/stat.h>
 #include <linux/init.h>
 
 #include <scsi/scsi_host.h>
Index: linux/drivers/scsi/t128.c
===================================================================
--- linux.orig/drivers/scsi/t128.c	2015-11-18 19:33:27.000000000 +1100
+++ linux/drivers/scsi/t128.c	2015-11-18 19:34:01.000000000 +1100
@@ -68,14 +68,11 @@
  * 15 9-11
  */
  
-#include <linux/signal.h>
 #include <linux/io.h>
 #include <linux/blkdev.h>
 #include <linux/interrupt.h>
-#include <linux/stat.h>
 #include <linux/init.h>
 #include <linux/module.h>
-#include <linux/delay.h>
 
 #include <scsi/scsi_host.h>
 #include "t128.h"



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

* [PATCH 45/71] ncr5380: Cleanup #include directives
@ 2015-11-18  8:35   ` Finn Thain
  0 siblings, 0 replies; 268+ messages in thread
From: Finn Thain @ 2015-11-18  8:35 UTC (permalink / raw)
  To: James E.J. Bottomley, Michael Schmitz, linux-m68k, linux-scsi,
	linux-kernel, Russell King, linux-arm-kernel

[-- Attachment #1: ncr5380-move-core-driver-includes --]
[-- Type: text/plain, Size: 7520 bytes --]

Remove unused includes (stat.h, signal.h, proc_fs.h) and move includes
needed by the core drivers into the common header (delay.h etc).

Signed-off-by: Finn Thain <fthain@telegraphics.com.au>

---
 drivers/scsi/NCR5380.c       |    2 --
 drivers/scsi/NCR5380.h       |    4 ++++
 drivers/scsi/arm/cumana_1.c  |    4 ----
 drivers/scsi/arm/oak.c       |    2 --
 drivers/scsi/atari_NCR5380.c |    5 -----
 drivers/scsi/atari_scsi.c    |    1 -
 drivers/scsi/dmx3191d.c      |    5 -----
 drivers/scsi/dtc.c           |    4 +---
 drivers/scsi/g_NCR5380.c     |    6 ++----
 drivers/scsi/mac_scsi.c      |    1 -
 drivers/scsi/pas16.c         |    4 ----
 drivers/scsi/t128.c          |    3 ---
 12 files changed, 7 insertions(+), 34 deletions(-)

Index: linux/drivers/scsi/NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/NCR5380.c	2015-11-18 19:34:00.000000000 +1100
+++ linux/drivers/scsi/NCR5380.c	2015-11-18 19:34:01.000000000 +1100
@@ -79,8 +79,6 @@
  * 4.  Test SCSI-II tagged queueing (I have no devices which support 
  *      tagged queueing)
  */
-#include <scsi/scsi_dbg.h>
-#include <scsi/scsi_transport_spi.h>
 
 #if (NDEBUG & NDEBUG_LISTS)
 #define LIST(x,y) {printk("LINE:%d   Adding %p to %p\n", __LINE__, (void*)(x), (void*)(y)); if ((x)==(y)) udelay(5); }
Index: linux/drivers/scsi/NCR5380.h
===================================================================
--- linux.orig/drivers/scsi/NCR5380.h	2015-11-18 19:33:56.000000000 +1100
+++ linux/drivers/scsi/NCR5380.h	2015-11-18 19:34:01.000000000 +1100
@@ -22,8 +22,12 @@
 #ifndef NCR5380_H
 #define NCR5380_H
 
+#include <linux/delay.h>
 #include <linux/interrupt.h>
+#include <linux/workqueue.h>
+#include <scsi/scsi_dbg.h>
 #include <scsi/scsi_eh.h>
+#include <scsi/scsi_transport_spi.h>
 
 #define NDEBUG_ARBITRATION	0x1
 #define NDEBUG_AUTOSENSE	0x2
Index: linux/drivers/scsi/arm/cumana_1.c
===================================================================
--- linux.orig/drivers/scsi/arm/cumana_1.c	2015-11-18 19:33:35.000000000 +1100
+++ linux/drivers/scsi/arm/cumana_1.c	2015-11-18 19:34:01.000000000 +1100
@@ -4,9 +4,7 @@
  * Copyright 1995-2002, Russell King
  */
 #include <linux/module.h>
-#include <linux/signal.h>
 #include <linux/ioport.h>
-#include <linux/delay.h>
 #include <linux/blkdev.h>
 #include <linux/init.h>
 
@@ -15,8 +13,6 @@
 
 #include <scsi/scsi_host.h>
 
-#include <scsi/scsicam.h>
-
 #define PSEUDO_DMA
 
 #define priv(host)			((struct NCR5380_hostdata *)(host)->hostdata)
Index: linux/drivers/scsi/arm/oak.c
===================================================================
--- linux.orig/drivers/scsi/arm/oak.c	2015-11-18 19:33:35.000000000 +1100
+++ linux/drivers/scsi/arm/oak.c	2015-11-18 19:34:01.000000000 +1100
@@ -5,9 +5,7 @@
  */
 
 #include <linux/module.h>
-#include <linux/signal.h>
 #include <linux/ioport.h>
-#include <linux/delay.h>
 #include <linux/blkdev.h>
 #include <linux/init.h>
 
Index: linux/drivers/scsi/atari_NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/atari_NCR5380.c	2015-11-18 19:34:00.000000000 +1100
+++ linux/drivers/scsi/atari_NCR5380.c	2015-11-18 19:34:01.000000000 +1100
@@ -68,9 +68,6 @@
 
 /* Adapted for the sun3 by Sam Creasey. */
 
-#include <scsi/scsi_dbg.h>
-#include <scsi/scsi_transport_spi.h>
-
 #if (NDEBUG & NDEBUG_LISTS)
 #define LIST(x, y)						\
 	do {							\
@@ -528,8 +525,6 @@ static inline int NCR5380_poll_politely(
 	                                        reg, bit, val, wait);
 }
 
-#include <linux/delay.h>
-
 #if NDEBUG
 static struct {
 	unsigned char mask;
Index: linux/drivers/scsi/atari_scsi.c
===================================================================
--- linux.orig/drivers/scsi/atari_scsi.c	2015-11-18 19:33:27.000000000 +1100
+++ linux/drivers/scsi/atari_scsi.c	2015-11-18 19:34:01.000000000 +1100
@@ -66,7 +66,6 @@
 
 #include <linux/module.h>
 #include <linux/types.h>
-#include <linux/delay.h>
 #include <linux/blkdev.h>
 #include <linux/interrupt.h>
 #include <linux/init.h>
Index: linux/drivers/scsi/dmx3191d.c
===================================================================
--- linux.orig/drivers/scsi/dmx3191d.c	2015-11-18 19:33:27.000000000 +1100
+++ linux/drivers/scsi/dmx3191d.c	2015-11-18 19:34:01.000000000 +1100
@@ -41,11 +41,6 @@
 
 #define NCR5380_implementation_fields	/* none */
 
-/*
- * Includes needed for NCR5380.[ch] (XXX: Move them to NCR5380.h)
- */
-#include <linux/delay.h>
-
 #include "NCR5380.h"
 #include "NCR5380.c"
 
Index: linux/drivers/scsi/dtc.c
===================================================================
--- linux.orig/drivers/scsi/dtc.c	2015-11-18 19:33:56.000000000 +1100
+++ linux/drivers/scsi/dtc.c	2015-11-18 19:34:01.000000000 +1100
@@ -46,15 +46,13 @@
 
 
 #include <linux/module.h>
-#include <linux/signal.h>
 #include <linux/blkdev.h>
-#include <linux/delay.h>
-#include <linux/stat.h>
 #include <linux/string.h>
 #include <linux/init.h>
 #include <linux/interrupt.h>
 #include <linux/io.h>
 #include <scsi/scsi_host.h>
+
 #include "dtc.h"
 #define AUTOPROBE_IRQ
 #include "NCR5380.h"
Index: linux/drivers/scsi/g_NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/g_NCR5380.c	2015-11-18 19:33:56.000000000 +1100
+++ linux/drivers/scsi/g_NCR5380.c	2015-11-18 19:34:01.000000000 +1100
@@ -63,16 +63,14 @@
 #endif
 
 #include <asm/io.h>
-#include <linux/signal.h>
 #include <linux/blkdev.h>
+#include <linux/module.h>
 #include <scsi/scsi_host.h>
 #include "g_NCR5380.h"
 #include "NCR5380.h"
-#include <linux/stat.h>
 #include <linux/init.h>
 #include <linux/ioport.h>
 #include <linux/isapnp.h>
-#include <linux/delay.h>
 #include <linux/interrupt.h>
 
 static int ncr_irq;
@@ -733,7 +731,7 @@ static struct scsi_host_template driver_
 	.cmd_per_lun    	= CMD_PER_LUN,
         .use_clustering		= DISABLE_CLUSTERING,
 };
-#include <linux/module.h>
+
 #include "scsi_module.c"
 
 module_param(ncr_irq, int, 0);
Index: linux/drivers/scsi/mac_scsi.c
===================================================================
--- linux.orig/drivers/scsi/mac_scsi.c	2015-11-18 19:33:35.000000000 +1100
+++ linux/drivers/scsi/mac_scsi.c	2015-11-18 19:34:01.000000000 +1100
@@ -12,7 +12,6 @@
  */
 
 #include <linux/types.h>
-#include <linux/delay.h>
 #include <linux/module.h>
 #include <linux/ioport.h>
 #include <linux/init.h>
Index: linux/drivers/scsi/pas16.c
===================================================================
--- linux.orig/drivers/scsi/pas16.c	2015-11-18 19:33:52.000000000 +1100
+++ linux/drivers/scsi/pas16.c	2015-11-18 19:34:01.000000000 +1100
@@ -69,14 +69,10 @@
  
 #include <linux/module.h>
 
-#include <linux/signal.h>
-#include <linux/proc_fs.h>
 #include <asm/io.h>
 #include <asm/dma.h>
 #include <linux/blkdev.h>
-#include <linux/delay.h>
 #include <linux/interrupt.h>
-#include <linux/stat.h>
 #include <linux/init.h>
 
 #include <scsi/scsi_host.h>
Index: linux/drivers/scsi/t128.c
===================================================================
--- linux.orig/drivers/scsi/t128.c	2015-11-18 19:33:27.000000000 +1100
+++ linux/drivers/scsi/t128.c	2015-11-18 19:34:01.000000000 +1100
@@ -68,14 +68,11 @@
  * 15 9-11
  */
  
-#include <linux/signal.h>
 #include <linux/io.h>
 #include <linux/blkdev.h>
 #include <linux/interrupt.h>
-#include <linux/stat.h>
 #include <linux/init.h>
 #include <linux/module.h>
-#include <linux/delay.h>
 
 #include <scsi/scsi_host.h>
 #include "t128.h"

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

* [PATCH 45/71] ncr5380: Cleanup #include directives
@ 2015-11-18  8:35   ` Finn Thain
  0 siblings, 0 replies; 268+ messages in thread
From: Finn Thain @ 2015-11-18  8:35 UTC (permalink / raw)
  To: linux-arm-kernel

An embedded and charset-unspecified text was scrubbed...
Name: ncr5380-move-core-driver-includes
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20151118/acb2858d/attachment.ksh>

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

* [PATCH 46/71] ncr5380: Fix NDEBUG_NO_DATAOUT flag
  2015-11-18  8:34 ` Finn Thain
@ 2015-11-18  8:35   ` Finn Thain
  -1 siblings, 0 replies; 268+ messages in thread
From: Finn Thain @ 2015-11-18  8:35 UTC (permalink / raw)
  To: James E.J. Bottomley, Michael Schmitz, linux-m68k, linux-scsi,
	linux-kernel

[-- Attachment #1: ncr5380-fix-NDEBUG_NO_DATAOUT --]
[-- Type: text/plain, Size: 1048 bytes --]

NDEBUG_NO_DATAOUT should not disable DATA IN phases too. Fix this.
(This bug has long been fixed in atari_NCR5380.c.)

Signed-off-by: Finn Thain <fthain@telegraphics.com.au>

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

Index: linux/drivers/scsi/NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/NCR5380.c	2015-11-18 19:34:01.000000000 +1100
+++ linux/drivers/scsi/NCR5380.c	2015-11-18 19:34:04.000000000 +1100
@@ -1833,7 +1833,6 @@ static void NCR5380_information_transfer
 				continue;
 			}
 			switch (phase) {
-			case PHASE_DATAIN:
 			case PHASE_DATAOUT:
 #if (NDEBUG & NDEBUG_NO_DATAOUT)
 				printk("scsi%d : NDEBUG_NO_DATAOUT set, attempted DATAOUT aborted\n", instance->host_no);
@@ -1843,6 +1842,7 @@ static void NCR5380_information_transfer
 				cmd->scsi_done(cmd);
 				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.



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

* [PATCH 46/71] ncr5380: Fix NDEBUG_NO_DATAOUT flag
@ 2015-11-18  8:35   ` Finn Thain
  0 siblings, 0 replies; 268+ messages in thread
From: Finn Thain @ 2015-11-18  8:35 UTC (permalink / raw)
  To: James E.J. Bottomley, Michael Schmitz, linux-m68k, linux-scsi,
	linux-kernel

[-- Attachment #1: ncr5380-fix-NDEBUG_NO_DATAOUT --]
[-- Type: text/plain, Size: 1048 bytes --]

NDEBUG_NO_DATAOUT should not disable DATA IN phases too. Fix this.
(This bug has long been fixed in atari_NCR5380.c.)

Signed-off-by: Finn Thain <fthain@telegraphics.com.au>

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

Index: linux/drivers/scsi/NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/NCR5380.c	2015-11-18 19:34:01.000000000 +1100
+++ linux/drivers/scsi/NCR5380.c	2015-11-18 19:34:04.000000000 +1100
@@ -1833,7 +1833,6 @@ static void NCR5380_information_transfer
 				continue;
 			}
 			switch (phase) {
-			case PHASE_DATAIN:
 			case PHASE_DATAOUT:
 #if (NDEBUG & NDEBUG_NO_DATAOUT)
 				printk("scsi%d : NDEBUG_NO_DATAOUT set, attempted DATAOUT aborted\n", instance->host_no);
@@ -1843,6 +1842,7 @@ static void NCR5380_information_transfer
 				cmd->scsi_done(cmd);
 				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.



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

* [PATCH 47/71] ncr5380: Fix and cleanup scsi_host_template initializers
  2015-11-18  8:34 ` Finn Thain
@ 2015-11-18  8:35   ` Finn Thain
  -1 siblings, 0 replies; 268+ messages in thread
From: Finn Thain @ 2015-11-18  8:35 UTC (permalink / raw)
  To: James E.J. Bottomley, Michael Schmitz, linux-m68k, linux-scsi,
	linux-kernel

[-- Attachment #1: ncr5380-cleanup-scsi_host_template-initializers --]
[-- Type: text/plain, Size: 12491 bytes --]

Add missing .module initializer. Use distinct .proc_name values for the
g_NCR5380 and g_NCR5380_mmio modules. Remove pointless CAN_QUEUE and
CMD_PER_LUN override macros. Cleanup whitespace and code style.

Signed-off-by: Finn Thain <fthain@telegraphics.com.au>

---
 drivers/scsi/atari_scsi.c |    2 +-
 drivers/scsi/dmx3191d.c   |    1 +
 drivers/scsi/dtc.c        |   32 ++++++++++++++++----------------
 drivers/scsi/dtc.h        |    8 --------
 drivers/scsi/g_NCR5380.c  |   26 +++++++++++++-------------
 drivers/scsi/g_NCR5380.h  |   10 ++--------
 drivers/scsi/mac_scsi.c   |   28 ++++++++++++++--------------
 drivers/scsi/pas16.c      |   32 ++++++++++++++++----------------
 drivers/scsi/pas16.h      |    8 --------
 drivers/scsi/sun3_scsi.c  |    6 +++---
 drivers/scsi/t128.c       |   32 ++++++++++++++++----------------
 drivers/scsi/t128.h       |    8 --------
 12 files changed, 82 insertions(+), 111 deletions(-)

Index: linux/drivers/scsi/dmx3191d.c
===================================================================
--- linux.orig/drivers/scsi/dmx3191d.c	2015-11-18 19:34:01.000000000 +1100
+++ linux/drivers/scsi/dmx3191d.c	2015-11-18 19:34:05.000000000 +1100
@@ -49,6 +49,7 @@
 
 
 static struct scsi_host_template dmx3191d_driver_template = {
+	.module			= THIS_MODULE,
 	.proc_name		= DMX3191D_DRIVER_NAME,
 	.name			= "Domex DMX3191D",
 	.info			= NCR5380_info,
Index: linux/drivers/scsi/dtc.c
===================================================================
--- linux.orig/drivers/scsi/dtc.c	2015-11-18 19:34:01.000000000 +1100
+++ linux/drivers/scsi/dtc.c	2015-11-18 19:34:05.000000000 +1100
@@ -436,21 +436,21 @@ static int dtc_release(struct Scsi_Host
 }
 
 static struct scsi_host_template driver_template = {
-	.name				= "DTC 3180/3280 ",
-	.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,
-	.eh_bus_reset_handler		= dtc_bus_reset,
-	.bios_param     		= dtc_biosparam,
-	.can_queue      		= CAN_QUEUE,
-	.this_id        		= 7,
-	.sg_tablesize   		= SG_ALL,
-	.cmd_per_lun    		= CMD_PER_LUN,
-	.use_clustering 		= DISABLE_CLUSTERING,
+	.name			= "DTC 3180/3280",
+	.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,
+	.eh_bus_reset_handler	= dtc_bus_reset,
+	.bios_param		= dtc_biosparam,
+	.can_queue		= 32,
+	.this_id		= 7,
+	.sg_tablesize		= SG_ALL,
+	.cmd_per_lun		= 2,
+	.use_clustering		= DISABLE_CLUSTERING,
 };
 #include "scsi_module.c"
Index: linux/drivers/scsi/dtc.h
===================================================================
--- linux.orig/drivers/scsi/dtc.h	2015-11-18 19:33:35.000000000 +1100
+++ linux/drivers/scsi/dtc.h	2015-11-18 19:34:05.000000000 +1100
@@ -10,14 +10,6 @@
 #ifndef DTC3280_H
 #define DTC3280_H
 
-#ifndef CMD_PER_LUN
-#define CMD_PER_LUN 2
-#endif
-
-#ifndef CAN_QUEUE
-#define CAN_QUEUE 32 
-#endif
-
 #define NCR5380_implementation_fields \
     void __iomem *base
 
Index: linux/drivers/scsi/g_NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/g_NCR5380.c	2015-11-18 19:34:01.000000000 +1100
+++ linux/drivers/scsi/g_NCR5380.c	2015-11-18 19:34:05.000000000 +1100
@@ -305,7 +305,6 @@ static int __init generic_NCR5380_detect
 		}
 	}
 #endif
-	tpnt->proc_name = "g_NCR5380";
 
 	for (count = 0; current_override < NO_OVERRIDES; ++current_override) {
 		if (!(overrides[current_override].NCR5380_map_name))
@@ -716,20 +715,21 @@ static int generic_NCR5380_dma_xfer_len(
 #include "NCR5380.c"
 
 static struct scsi_host_template driver_template = {
-	.show_info      	= generic_NCR5380_show_info,
-	.name           	= "Generic NCR5380/NCR53C400 SCSI",
-	.detect         	= generic_NCR5380_detect,
-	.release        	= generic_NCR5380_release_resources,
-	.info           	= generic_NCR5380_info,
-	.queuecommand   	= generic_NCR5380_queue_command,
+	.proc_name		= DRV_MODULE_NAME,
+	.show_info		= generic_NCR5380_show_info,
+	.name			= "Generic NCR5380/NCR53C400 SCSI",
+	.detect			= generic_NCR5380_detect,
+	.release		= generic_NCR5380_release_resources,
+	.info			= generic_NCR5380_info,
+	.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      	= CAN_QUEUE,
-        .this_id        	= 7,
-        .sg_tablesize   	= SG_ALL,
-	.cmd_per_lun    	= CMD_PER_LUN,
-        .use_clustering		= DISABLE_CLUSTERING,
+	.bios_param		= NCR5380_BIOSPARAM,
+	.can_queue		= 16,
+	.this_id		= 7,
+	.sg_tablesize		= SG_ALL,
+	.cmd_per_lun		= 2,
+	.use_clustering		= DISABLE_CLUSTERING,
 };
 
 #include "scsi_module.c"
Index: linux/drivers/scsi/g_NCR5380.h
===================================================================
--- linux.orig/drivers/scsi/g_NCR5380.h	2015-11-18 19:33:35.000000000 +1100
+++ linux/drivers/scsi/g_NCR5380.h	2015-11-18 19:34:05.000000000 +1100
@@ -21,18 +21,11 @@
 #define NCR5380_BIOSPARAM NULL
 #endif
 
-#ifndef CMD_PER_LUN
-#define CMD_PER_LUN 2
-#endif
-
-#ifndef CAN_QUEUE
-#define CAN_QUEUE 16
-#endif
-
 #define __STRVAL(x) #x
 #define STRVAL(x) __STRVAL(x)
 
 #ifndef SCSI_G_NCR5380_MEM
+#define DRV_MODULE_NAME "g_NCR5380"
 
 #define NCR5380_map_type int
 #define NCR5380_map_name port
@@ -53,6 +46,7 @@
 
 #else 
 /* therefore SCSI_G_NCR5380_MEM */
+#define DRV_MODULE_NAME "g_NCR5380_mmio"
 
 #define NCR5380_map_type unsigned long
 #define NCR5380_map_name base
Index: linux/drivers/scsi/mac_scsi.c
===================================================================
--- linux.orig/drivers/scsi/mac_scsi.c	2015-11-18 19:34:01.000000000 +1100
+++ linux/drivers/scsi/mac_scsi.c	2015-11-18 19:34:05.000000000 +1100
@@ -309,20 +309,20 @@ static int macscsi_pwrite(struct Scsi_Ho
 #define PFX                     DRV_MODULE_NAME ": "
 
 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,
-	.eh_abort_handler		= macscsi_abort,
-	.eh_bus_reset_handler		= macscsi_bus_reset,
-	.can_queue			= 16,
-	.this_id			= 7,
-	.sg_tablesize			= SG_ALL,
-	.cmd_per_lun			= 2,
-	.use_clustering			= DISABLE_CLUSTERING
+	.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,
+	.eh_abort_handler	= macscsi_abort,
+	.eh_bus_reset_handler	= macscsi_bus_reset,
+	.can_queue		= 16,
+	.this_id		= 7,
+	.sg_tablesize		= SG_ALL,
+	.cmd_per_lun		= 2,
+	.use_clustering		= DISABLE_CLUSTERING,
 };
 
 static int __init mac_scsi_probe(struct platform_device *pdev)
Index: linux/drivers/scsi/pas16.c
===================================================================
--- linux.orig/drivers/scsi/pas16.c	2015-11-18 19:34:01.000000000 +1100
+++ linux/drivers/scsi/pas16.c	2015-11-18 19:34:05.000000000 +1100
@@ -546,22 +546,22 @@ static int pas16_release(struct Scsi_Hos
 }
 
 static struct scsi_host_template driver_template = {
-	.name           = "Pro Audio Spectrum-16 SCSI",
-	.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,
-	.eh_bus_reset_handler = pas16_bus_reset,
-	.bios_param     = pas16_biosparam, 
-	.can_queue      = CAN_QUEUE,
-	.this_id        = 7,
-	.sg_tablesize   = SG_ALL,
-	.cmd_per_lun    = CMD_PER_LUN,
-	.use_clustering = DISABLE_CLUSTERING,
+	.name			= "Pro Audio Spectrum-16 SCSI",
+	.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,
+	.eh_bus_reset_handler	= pas16_bus_reset,
+	.bios_param		= pas16_biosparam,
+	.can_queue		= 32,
+	.this_id		= 7,
+	.sg_tablesize		= SG_ALL,
+	.cmd_per_lun		= 2,
+	.use_clustering		= DISABLE_CLUSTERING,
 };
 #include "scsi_module.c"
 
Index: linux/drivers/scsi/pas16.h
===================================================================
--- linux.orig/drivers/scsi/pas16.h	2015-11-18 19:33:35.000000000 +1100
+++ linux/drivers/scsi/pas16.h	2015-11-18 19:34:05.000000000 +1100
@@ -95,14 +95,6 @@
 #define OPERATION_MODE_1 0xec03
 #define IO_CONFIG_3 0xf002
 
-#ifndef CMD_PER_LUN
-#define CMD_PER_LUN 2
-#endif
-
-#ifndef CAN_QUEUE
-#define CAN_QUEUE 32 
-#endif
-
 #define NCR5380_implementation_fields /* none */
 
 #define PAS16_io_port(reg) (instance->io_port + pas16_offset[(reg)])
Index: linux/drivers/scsi/sun3_scsi.c
===================================================================
--- linux.orig/drivers/scsi/sun3_scsi.c	2015-11-18 19:33:27.000000000 +1100
+++ linux/drivers/scsi/sun3_scsi.c	2015-11-18 19:34:05.000000000 +1100
@@ -463,13 +463,13 @@ static struct scsi_host_template sun3_sc
 	.name			= SUN3_SCSI_NAME,
 	.info			= sun3scsi_info,
 	.queuecommand		= sun3scsi_queue_command,
-	.eh_abort_handler      	= sun3scsi_abort,
-	.eh_bus_reset_handler  	= sun3scsi_bus_reset,
+	.eh_abort_handler	= sun3scsi_abort,
+	.eh_bus_reset_handler	= sun3scsi_bus_reset,
 	.can_queue		= 16,
 	.this_id		= 7,
 	.sg_tablesize		= SG_NONE,
 	.cmd_per_lun		= 2,
-	.use_clustering		= DISABLE_CLUSTERING
+	.use_clustering		= DISABLE_CLUSTERING,
 };
 
 static int __init sun3_scsi_probe(struct platform_device *pdev)
Index: linux/drivers/scsi/t128.c
===================================================================
--- linux.orig/drivers/scsi/t128.c	2015-11-18 19:34:01.000000000 +1100
+++ linux/drivers/scsi/t128.c	2015-11-18 19:34:05.000000000 +1100
@@ -390,21 +390,21 @@ MODULE_LICENSE("GPL");
 #include "NCR5380.c"
 
 static struct scsi_host_template driver_template = {
-	.name           = "Trantor T128/T128F/T228",
-	.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,
-	.eh_bus_reset_handler    = t128_bus_reset,
-	.bios_param     = t128_biosparam,
-	.can_queue      = CAN_QUEUE,
-        .this_id        = 7,
-	.sg_tablesize   = SG_ALL,
-	.cmd_per_lun    = CMD_PER_LUN,
-	.use_clustering = DISABLE_CLUSTERING,
+	.name			= "Trantor T128/T128F/T228",
+	.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,
+	.eh_bus_reset_handler	= t128_bus_reset,
+	.bios_param		= t128_biosparam,
+	.can_queue		= 32,
+	.this_id		= 7,
+	.sg_tablesize		= SG_ALL,
+	.cmd_per_lun		= 2,
+	.use_clustering		= DISABLE_CLUSTERING,
 };
 #include "scsi_module.c"
Index: linux/drivers/scsi/t128.h
===================================================================
--- linux.orig/drivers/scsi/t128.h	2015-11-18 19:33:35.000000000 +1100
+++ linux/drivers/scsi/t128.h	2015-11-18 19:34:05.000000000 +1100
@@ -67,14 +67,6 @@
 
 #define T_DATA_REG_OFFSET	0x1e00	/* rw 512 bytes long */
 
-#ifndef CMD_PER_LUN
-#define CMD_PER_LUN 2
-#endif
-
-#ifndef CAN_QUEUE
-#define CAN_QUEUE 32
-#endif
-
 #define NCR5380_implementation_fields \
     void __iomem *base
 
Index: linux/drivers/scsi/atari_scsi.c
===================================================================
--- linux.orig/drivers/scsi/atari_scsi.c	2015-11-18 19:34:01.000000000 +1100
+++ linux/drivers/scsi/atari_scsi.c	2015-11-18 19:34:05.000000000 +1100
@@ -781,7 +781,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,
-	.use_clustering		= DISABLE_CLUSTERING
+	.use_clustering		= DISABLE_CLUSTERING,
 };
 
 static int __init atari_scsi_probe(struct platform_device *pdev)



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

* [PATCH 47/71] ncr5380: Fix and cleanup scsi_host_template initializers
@ 2015-11-18  8:35   ` Finn Thain
  0 siblings, 0 replies; 268+ messages in thread
From: Finn Thain @ 2015-11-18  8:35 UTC (permalink / raw)
  To: James E.J. Bottomley, Michael Schmitz, linux-m68k, linux-scsi,
	linux-kernel

[-- Attachment #1: ncr5380-cleanup-scsi_host_template-initializers --]
[-- Type: text/plain, Size: 12489 bytes --]

Add missing .module initializer. Use distinct .proc_name values for the
g_NCR5380 and g_NCR5380_mmio modules. Remove pointless CAN_QUEUE and
CMD_PER_LUN override macros. Cleanup whitespace and code style.

Signed-off-by: Finn Thain <fthain@telegraphics.com.au>

---
 drivers/scsi/atari_scsi.c |    2 +-
 drivers/scsi/dmx3191d.c   |    1 +
 drivers/scsi/dtc.c        |   32 ++++++++++++++++----------------
 drivers/scsi/dtc.h        |    8 --------
 drivers/scsi/g_NCR5380.c  |   26 +++++++++++++-------------
 drivers/scsi/g_NCR5380.h  |   10 ++--------
 drivers/scsi/mac_scsi.c   |   28 ++++++++++++++--------------
 drivers/scsi/pas16.c      |   32 ++++++++++++++++----------------
 drivers/scsi/pas16.h      |    8 --------
 drivers/scsi/sun3_scsi.c  |    6 +++---
 drivers/scsi/t128.c       |   32 ++++++++++++++++----------------
 drivers/scsi/t128.h       |    8 --------
 12 files changed, 82 insertions(+), 111 deletions(-)

Index: linux/drivers/scsi/dmx3191d.c
===================================================================
--- linux.orig/drivers/scsi/dmx3191d.c	2015-11-18 19:34:01.000000000 +1100
+++ linux/drivers/scsi/dmx3191d.c	2015-11-18 19:34:05.000000000 +1100
@@ -49,6 +49,7 @@
 
 
 static struct scsi_host_template dmx3191d_driver_template = {
+	.module			= THIS_MODULE,
 	.proc_name		= DMX3191D_DRIVER_NAME,
 	.name			= "Domex DMX3191D",
 	.info			= NCR5380_info,
Index: linux/drivers/scsi/dtc.c
===================================================================
--- linux.orig/drivers/scsi/dtc.c	2015-11-18 19:34:01.000000000 +1100
+++ linux/drivers/scsi/dtc.c	2015-11-18 19:34:05.000000000 +1100
@@ -436,21 +436,21 @@ static int dtc_release(struct Scsi_Host
 }
 
 static struct scsi_host_template driver_template = {
-	.name				= "DTC 3180/3280 ",
-	.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,
-	.eh_bus_reset_handler		= dtc_bus_reset,
-	.bios_param     		= dtc_biosparam,
-	.can_queue      		= CAN_QUEUE,
-	.this_id        		= 7,
-	.sg_tablesize   		= SG_ALL,
-	.cmd_per_lun    		= CMD_PER_LUN,
-	.use_clustering 		= DISABLE_CLUSTERING,
+	.name			= "DTC 3180/3280",
+	.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,
+	.eh_bus_reset_handler	= dtc_bus_reset,
+	.bios_param		= dtc_biosparam,
+	.can_queue		= 32,
+	.this_id		= 7,
+	.sg_tablesize		= SG_ALL,
+	.cmd_per_lun		= 2,
+	.use_clustering		= DISABLE_CLUSTERING,
 };
 #include "scsi_module.c"
Index: linux/drivers/scsi/dtc.h
===================================================================
--- linux.orig/drivers/scsi/dtc.h	2015-11-18 19:33:35.000000000 +1100
+++ linux/drivers/scsi/dtc.h	2015-11-18 19:34:05.000000000 +1100
@@ -10,14 +10,6 @@
 #ifndef DTC3280_H
 #define DTC3280_H
 
-#ifndef CMD_PER_LUN
-#define CMD_PER_LUN 2
-#endif
-
-#ifndef CAN_QUEUE
-#define CAN_QUEUE 32 
-#endif
-
 #define NCR5380_implementation_fields \
     void __iomem *base
 
Index: linux/drivers/scsi/g_NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/g_NCR5380.c	2015-11-18 19:34:01.000000000 +1100
+++ linux/drivers/scsi/g_NCR5380.c	2015-11-18 19:34:05.000000000 +1100
@@ -305,7 +305,6 @@ static int __init generic_NCR5380_detect
 		}
 	}
 #endif
-	tpnt->proc_name = "g_NCR5380";
 
 	for (count = 0; current_override < NO_OVERRIDES; ++current_override) {
 		if (!(overrides[current_override].NCR5380_map_name))
@@ -716,20 +715,21 @@ static int generic_NCR5380_dma_xfer_len(
 #include "NCR5380.c"
 
 static struct scsi_host_template driver_template = {
-	.show_info      	= generic_NCR5380_show_info,
-	.name           	= "Generic NCR5380/NCR53C400 SCSI",
-	.detect         	= generic_NCR5380_detect,
-	.release        	= generic_NCR5380_release_resources,
-	.info           	= generic_NCR5380_info,
-	.queuecommand   	= generic_NCR5380_queue_command,
+	.proc_name		= DRV_MODULE_NAME,
+	.show_info		= generic_NCR5380_show_info,
+	.name			= "Generic NCR5380/NCR53C400 SCSI",
+	.detect			= generic_NCR5380_detect,
+	.release		= generic_NCR5380_release_resources,
+	.info			= generic_NCR5380_info,
+	.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      	= CAN_QUEUE,
-        .this_id        	= 7,
-        .sg_tablesize   	= SG_ALL,
-	.cmd_per_lun    	= CMD_PER_LUN,
-        .use_clustering		= DISABLE_CLUSTERING,
+	.bios_param		= NCR5380_BIOSPARAM,
+	.can_queue		= 16,
+	.this_id		= 7,
+	.sg_tablesize		= SG_ALL,
+	.cmd_per_lun		= 2,
+	.use_clustering		= DISABLE_CLUSTERING,
 };
 
 #include "scsi_module.c"
Index: linux/drivers/scsi/g_NCR5380.h
===================================================================
--- linux.orig/drivers/scsi/g_NCR5380.h	2015-11-18 19:33:35.000000000 +1100
+++ linux/drivers/scsi/g_NCR5380.h	2015-11-18 19:34:05.000000000 +1100
@@ -21,18 +21,11 @@
 #define NCR5380_BIOSPARAM NULL
 #endif
 
-#ifndef CMD_PER_LUN
-#define CMD_PER_LUN 2
-#endif
-
-#ifndef CAN_QUEUE
-#define CAN_QUEUE 16
-#endif
-
 #define __STRVAL(x) #x
 #define STRVAL(x) __STRVAL(x)
 
 #ifndef SCSI_G_NCR5380_MEM
+#define DRV_MODULE_NAME "g_NCR5380"
 
 #define NCR5380_map_type int
 #define NCR5380_map_name port
@@ -53,6 +46,7 @@
 
 #else 
 /* therefore SCSI_G_NCR5380_MEM */
+#define DRV_MODULE_NAME "g_NCR5380_mmio"
 
 #define NCR5380_map_type unsigned long
 #define NCR5380_map_name base
Index: linux/drivers/scsi/mac_scsi.c
===================================================================
--- linux.orig/drivers/scsi/mac_scsi.c	2015-11-18 19:34:01.000000000 +1100
+++ linux/drivers/scsi/mac_scsi.c	2015-11-18 19:34:05.000000000 +1100
@@ -309,20 +309,20 @@ static int macscsi_pwrite(struct Scsi_Ho
 #define PFX                     DRV_MODULE_NAME ": "
 
 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,
-	.eh_abort_handler		= macscsi_abort,
-	.eh_bus_reset_handler		= macscsi_bus_reset,
-	.can_queue			= 16,
-	.this_id			= 7,
-	.sg_tablesize			= SG_ALL,
-	.cmd_per_lun			= 2,
-	.use_clustering			= DISABLE_CLUSTERING
+	.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,
+	.eh_abort_handler	= macscsi_abort,
+	.eh_bus_reset_handler	= macscsi_bus_reset,
+	.can_queue		= 16,
+	.this_id		= 7,
+	.sg_tablesize		= SG_ALL,
+	.cmd_per_lun		= 2,
+	.use_clustering		= DISABLE_CLUSTERING,
 };
 
 static int __init mac_scsi_probe(struct platform_device *pdev)
Index: linux/drivers/scsi/pas16.c
===================================================================
--- linux.orig/drivers/scsi/pas16.c	2015-11-18 19:34:01.000000000 +1100
+++ linux/drivers/scsi/pas16.c	2015-11-18 19:34:05.000000000 +1100
@@ -546,22 +546,22 @@ static int pas16_release(struct Scsi_Hos
 }
 
 static struct scsi_host_template driver_template = {
-	.name           = "Pro Audio Spectrum-16 SCSI",
-	.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,
-	.eh_bus_reset_handler = pas16_bus_reset,
-	.bios_param     = pas16_biosparam, 
-	.can_queue      = CAN_QUEUE,
-	.this_id        = 7,
-	.sg_tablesize   = SG_ALL,
-	.cmd_per_lun    = CMD_PER_LUN,
-	.use_clustering = DISABLE_CLUSTERING,
+	.name			= "Pro Audio Spectrum-16 SCSI",
+	.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,
+	.eh_bus_reset_handler	= pas16_bus_reset,
+	.bios_param		= pas16_biosparam,
+	.can_queue		= 32,
+	.this_id		= 7,
+	.sg_tablesize		= SG_ALL,
+	.cmd_per_lun		= 2,
+	.use_clustering		= DISABLE_CLUSTERING,
 };
 #include "scsi_module.c"
 
Index: linux/drivers/scsi/pas16.h
===================================================================
--- linux.orig/drivers/scsi/pas16.h	2015-11-18 19:33:35.000000000 +1100
+++ linux/drivers/scsi/pas16.h	2015-11-18 19:34:05.000000000 +1100
@@ -95,14 +95,6 @@
 #define OPERATION_MODE_1 0xec03
 #define IO_CONFIG_3 0xf002
 
-#ifndef CMD_PER_LUN
-#define CMD_PER_LUN 2
-#endif
-
-#ifndef CAN_QUEUE
-#define CAN_QUEUE 32 
-#endif
-
 #define NCR5380_implementation_fields /* none */
 
 #define PAS16_io_port(reg) (instance->io_port + pas16_offset[(reg)])
Index: linux/drivers/scsi/sun3_scsi.c
===================================================================
--- linux.orig/drivers/scsi/sun3_scsi.c	2015-11-18 19:33:27.000000000 +1100
+++ linux/drivers/scsi/sun3_scsi.c	2015-11-18 19:34:05.000000000 +1100
@@ -463,13 +463,13 @@ static struct scsi_host_template sun3_sc
 	.name			= SUN3_SCSI_NAME,
 	.info			= sun3scsi_info,
 	.queuecommand		= sun3scsi_queue_command,
-	.eh_abort_handler      	= sun3scsi_abort,
-	.eh_bus_reset_handler  	= sun3scsi_bus_reset,
+	.eh_abort_handler	= sun3scsi_abort,
+	.eh_bus_reset_handler	= sun3scsi_bus_reset,
 	.can_queue		= 16,
 	.this_id		= 7,
 	.sg_tablesize		= SG_NONE,
 	.cmd_per_lun		= 2,
-	.use_clustering		= DISABLE_CLUSTERING
+	.use_clustering		= DISABLE_CLUSTERING,
 };
 
 static int __init sun3_scsi_probe(struct platform_device *pdev)
Index: linux/drivers/scsi/t128.c
===================================================================
--- linux.orig/drivers/scsi/t128.c	2015-11-18 19:34:01.000000000 +1100
+++ linux/drivers/scsi/t128.c	2015-11-18 19:34:05.000000000 +1100
@@ -390,21 +390,21 @@ MODULE_LICENSE("GPL");
 #include "NCR5380.c"
 
 static struct scsi_host_template driver_template = {
-	.name           = "Trantor T128/T128F/T228",
-	.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,
-	.eh_bus_reset_handler    = t128_bus_reset,
-	.bios_param     = t128_biosparam,
-	.can_queue      = CAN_QUEUE,
-        .this_id        = 7,
-	.sg_tablesize   = SG_ALL,
-	.cmd_per_lun    = CMD_PER_LUN,
-	.use_clustering = DISABLE_CLUSTERING,
+	.name			= "Trantor T128/T128F/T228",
+	.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,
+	.eh_bus_reset_handler	= t128_bus_reset,
+	.bios_param		= t128_biosparam,
+	.can_queue		= 32,
+	.this_id		= 7,
+	.sg_tablesize		= SG_ALL,
+	.cmd_per_lun		= 2,
+	.use_clustering		= DISABLE_CLUSTERING,
 };
 #include "scsi_module.c"
Index: linux/drivers/scsi/t128.h
===================================================================
--- linux.orig/drivers/scsi/t128.h	2015-11-18 19:33:35.000000000 +1100
+++ linux/drivers/scsi/t128.h	2015-11-18 19:34:05.000000000 +1100
@@ -67,14 +67,6 @@
 
 #define T_DATA_REG_OFFSET	0x1e00	/* rw 512 bytes long */
 
-#ifndef CMD_PER_LUN
-#define CMD_PER_LUN 2
-#endif
-
-#ifndef CAN_QUEUE
-#define CAN_QUEUE 32
-#endif
-
 #define NCR5380_implementation_fields \
     void __iomem *base
 
Index: linux/drivers/scsi/atari_scsi.c
===================================================================
--- linux.orig/drivers/scsi/atari_scsi.c	2015-11-18 19:34:01.000000000 +1100
+++ linux/drivers/scsi/atari_scsi.c	2015-11-18 19:34:05.000000000 +1100
@@ -781,7 +781,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,
-	.use_clustering		= DISABLE_CLUSTERING
+	.use_clustering		= DISABLE_CLUSTERING,
 };
 
 static int __init atari_scsi_probe(struct platform_device *pdev)

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

* [PATCH 48/71] atari_NCR5380: Fix queue_size limit
  2015-11-18  8:34 ` Finn Thain
@ 2015-11-18  8:35   ` Finn Thain
  -1 siblings, 0 replies; 268+ messages in thread
From: Finn Thain @ 2015-11-18  8:35 UTC (permalink / raw)
  To: James E.J. Bottomley, Michael Schmitz, linux-m68k, linux-scsi,
	linux-kernel

[-- Attachment #1: atari_NCR5380-fix-queue_size-limit --]
[-- Type: text/plain, Size: 2368 bytes --]

When a target reports a QUEUE_FULL condition it causes the driver to
update the 'queue_size' limit with the number of currently allocated tags.
At least, that's what's supposed to happen, according to the comments.
Unfortunately the terms in the assignment are swapped. Fix this and
cleanup some obsolete comments.

Signed-off-by: Finn Thain <fthain@telegraphics.com.au>

---
 drivers/scsi/atari_NCR5380.c |   14 ++------------
 1 file changed, 2 insertions(+), 12 deletions(-)

Index: linux/drivers/scsi/atari_NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/atari_NCR5380.c	2015-11-18 19:34:01.000000000 +1100
+++ linux/drivers/scsi/atari_NCR5380.c	2015-11-18 19:34:08.000000000 +1100
@@ -229,9 +229,7 @@ static void do_reset(struct Scsi_Host *)
  * 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. The command is returned to the mid-level, but with status changed
- * to BUSY, since --as I've seen-- the mid-level can't handle QUEUE_FULL
- * correctly.
+ * 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
@@ -2148,21 +2146,13 @@ static void NCR5380_information_transfer
 #ifdef SUPPORT_TAGS
 					cmd_free_tag(cmd);
 					if (status_byte(cmd->SCp.Status) == QUEUE_FULL) {
-						/* Turn a QUEUE FULL status into BUSY, I think the
-						 * mid level cannot handle QUEUE FULL :-( (The
-						 * command is retried after BUSY). Also update our
-						 * queue size to the number of currently issued
-						 * commands now.
-						 */
-						/* ++Andreas: the mid level code knows about
-						   QUEUE_FULL now. */
 						struct tag_alloc *ta = &hostdata->TagAlloc[scmd_id(cmd)][cmd->device->lun];
 						dprintk(NDEBUG_TAGS, "scsi%d: target %d lun %llu returned "
 							   "QUEUE_FULL after %d commands\n",
 							   HOSTNO, cmd->device->id, cmd->device->lun,
 							   ta->nr_allocated);
 						if (ta->queue_size > ta->nr_allocated)
-							ta->nr_allocated = ta->queue_size;
+							ta->queue_size = ta->nr_allocated;
 					}
 #else
 					hostdata->busy[cmd->device->id] &= ~(1 << cmd->device->lun);



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

* [PATCH 48/71] atari_NCR5380: Fix queue_size limit
@ 2015-11-18  8:35   ` Finn Thain
  0 siblings, 0 replies; 268+ messages in thread
From: Finn Thain @ 2015-11-18  8:35 UTC (permalink / raw)
  To: James E.J. Bottomley, Michael Schmitz, linux-m68k, linux-scsi,
	linux-kernel

[-- Attachment #1: atari_NCR5380-fix-queue_size-limit --]
[-- Type: text/plain, Size: 2366 bytes --]

When a target reports a QUEUE_FULL condition it causes the driver to
update the 'queue_size' limit with the number of currently allocated tags.
At least, that's what's supposed to happen, according to the comments.
Unfortunately the terms in the assignment are swapped. Fix this and
cleanup some obsolete comments.

Signed-off-by: Finn Thain <fthain@telegraphics.com.au>

---
 drivers/scsi/atari_NCR5380.c |   14 ++------------
 1 file changed, 2 insertions(+), 12 deletions(-)

Index: linux/drivers/scsi/atari_NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/atari_NCR5380.c	2015-11-18 19:34:01.000000000 +1100
+++ linux/drivers/scsi/atari_NCR5380.c	2015-11-18 19:34:08.000000000 +1100
@@ -229,9 +229,7 @@ static void do_reset(struct Scsi_Host *)
  * 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. The command is returned to the mid-level, but with status changed
- * to BUSY, since --as I've seen-- the mid-level can't handle QUEUE_FULL
- * correctly.
+ * 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
@@ -2148,21 +2146,13 @@ static void NCR5380_information_transfer
 #ifdef SUPPORT_TAGS
 					cmd_free_tag(cmd);
 					if (status_byte(cmd->SCp.Status) == QUEUE_FULL) {
-						/* Turn a QUEUE FULL status into BUSY, I think the
-						 * mid level cannot handle QUEUE FULL :-( (The
-						 * command is retried after BUSY). Also update our
-						 * queue size to the number of currently issued
-						 * commands now.
-						 */
-						/* ++Andreas: the mid level code knows about
-						   QUEUE_FULL now. */
 						struct tag_alloc *ta = &hostdata->TagAlloc[scmd_id(cmd)][cmd->device->lun];
 						dprintk(NDEBUG_TAGS, "scsi%d: target %d lun %llu returned "
 							   "QUEUE_FULL after %d commands\n",
 							   HOSTNO, cmd->device->id, cmd->device->lun,
 							   ta->nr_allocated);
 						if (ta->queue_size > ta->nr_allocated)
-							ta->nr_allocated = ta->queue_size;
+							ta->queue_size = ta->nr_allocated;
 					}
 #else
 					hostdata->busy[cmd->device->id] &= ~(1 << cmd->device->lun);

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

* [PATCH 49/71] atari_NCR5380: Introduce FLAG_DTC3181E
  2015-11-18  8:34 ` Finn Thain
@ 2015-11-18  8:35   ` Finn Thain
  -1 siblings, 0 replies; 268+ messages in thread
From: Finn Thain @ 2015-11-18  8:35 UTC (permalink / raw)
  To: James E.J. Bottomley, Michael Schmitz, linux-m68k, linux-scsi,
	linux-kernel

[-- Attachment #1: atari_NCR5380-FLAG_DTC3181E --]
[-- Type: text/plain, Size: 3064 bytes --]

The atari_NCR5380.c core driver lacks the DTC special case found in
NCR5380.c. Add this special case. This reduces divergence between them
and allows drivers like dmx3191d to make use of atari_NCR5380.c which is
helpful for testing.

Signed-off-by: Finn Thain <fthain@telegraphics.com.au>

---
 drivers/scsi/NCR5380.c       |    7 +++----
 drivers/scsi/atari_NCR5380.c |   11 ++++++++---
 2 files changed, 11 insertions(+), 7 deletions(-)

Index: linux/drivers/scsi/atari_NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/atari_NCR5380.c	2015-11-18 19:34:08.000000000 +1100
+++ linux/drivers/scsi/atari_NCR5380.c	2015-11-18 19:34:08.000000000 +1100
@@ -646,12 +646,13 @@ static void prepare_info(struct Scsi_Hos
 	         "base 0x%lx, irq %d, "
 	         "can_queue %d, cmd_per_lun %d, "
 	         "sg_tablesize %d, this_id %d, "
-	         "flags { %s%s}, "
+	         "flags { %s%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_DTC3181E       ? "DTC3181E "       : "",
 	         hostdata->flags & FLAG_TAGGED_QUEUING ? "TAGGED_QUEUING " : "",
 	         hostdata->flags & FLAG_TOSHIBA_DELAY  ? "TOSHIBA_DELAY "  : "",
 #ifdef DIFFERENTIAL
@@ -1416,8 +1417,12 @@ static int NCR5380_select(struct Scsi_Ho
 	NCR5380_write(INITIATOR_COMMAND_REG,
 		      ICR_BASE | ICR_ASSERT_SEL | ICR_ASSERT_BSY);
 
-	if ((NCR5380_read(INITIATOR_COMMAND_REG) & ICR_ARBITRATION_LOST) ||
-	    hostdata->connected) {
+	/* RvC: DTC3181E has some trouble with this so we simply removed it.
+	 * Seems to work with only Mustek scanner attached.
+	 */
+	if (!(hostdata->flags & FLAG_DTC3181E) &&
+	    ((NCR5380_read(INITIATOR_COMMAND_REG) & ICR_ARBITRATION_LOST) ||
+	     hostdata->connected)) {
 		NCR5380_write(MODE_REG, MR_BASE);
 		NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
 		dprintk(NDEBUG_ARBITRATION, "scsi%d: lost arbitration, deasserting ICR_ASSERT_SEL\n",
Index: linux/drivers/scsi/NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/NCR5380.c	2015-11-18 19:34:04.000000000 +1100
+++ linux/drivers/scsi/NCR5380.c	2015-11-18 19:34:08.000000000 +1100
@@ -1154,11 +1154,10 @@ static int NCR5380_select(struct Scsi_Ho
 	NCR5380_write(INITIATOR_COMMAND_REG,
 		      ICR_BASE | ICR_ASSERT_SEL | ICR_ASSERT_BSY);
 
+	/* RvC: DTC3181E has some trouble with this so we simply removed it.
+	 * Seems to work with only Mustek scanner attached.
+	 */
 	if (!(hostdata->flags & FLAG_DTC3181E) &&
-	    /* RvC: DTC3181E has some trouble with this
-	     *      so we simply removed it. Seems to work with
-	     *      only Mustek scanner attached
-	     */
 	    (NCR5380_read(INITIATOR_COMMAND_REG) & ICR_ARBITRATION_LOST)) {
 		NCR5380_write(MODE_REG, MR_BASE);
 		NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);



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

* [PATCH 49/71] atari_NCR5380: Introduce FLAG_DTC3181E
@ 2015-11-18  8:35   ` Finn Thain
  0 siblings, 0 replies; 268+ messages in thread
From: Finn Thain @ 2015-11-18  8:35 UTC (permalink / raw)
  To: James E.J. Bottomley, Michael Schmitz, linux-m68k, linux-scsi,
	linux-kernel

[-- Attachment #1: atari_NCR5380-FLAG_DTC3181E --]
[-- Type: text/plain, Size: 3062 bytes --]

The atari_NCR5380.c core driver lacks the DTC special case found in
NCR5380.c. Add this special case. This reduces divergence between them
and allows drivers like dmx3191d to make use of atari_NCR5380.c which is
helpful for testing.

Signed-off-by: Finn Thain <fthain@telegraphics.com.au>

---
 drivers/scsi/NCR5380.c       |    7 +++----
 drivers/scsi/atari_NCR5380.c |   11 ++++++++---
 2 files changed, 11 insertions(+), 7 deletions(-)

Index: linux/drivers/scsi/atari_NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/atari_NCR5380.c	2015-11-18 19:34:08.000000000 +1100
+++ linux/drivers/scsi/atari_NCR5380.c	2015-11-18 19:34:08.000000000 +1100
@@ -646,12 +646,13 @@ static void prepare_info(struct Scsi_Hos
 	         "base 0x%lx, irq %d, "
 	         "can_queue %d, cmd_per_lun %d, "
 	         "sg_tablesize %d, this_id %d, "
-	         "flags { %s%s}, "
+	         "flags { %s%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_DTC3181E       ? "DTC3181E "       : "",
 	         hostdata->flags & FLAG_TAGGED_QUEUING ? "TAGGED_QUEUING " : "",
 	         hostdata->flags & FLAG_TOSHIBA_DELAY  ? "TOSHIBA_DELAY "  : "",
 #ifdef DIFFERENTIAL
@@ -1416,8 +1417,12 @@ static int NCR5380_select(struct Scsi_Ho
 	NCR5380_write(INITIATOR_COMMAND_REG,
 		      ICR_BASE | ICR_ASSERT_SEL | ICR_ASSERT_BSY);
 
-	if ((NCR5380_read(INITIATOR_COMMAND_REG) & ICR_ARBITRATION_LOST) ||
-	    hostdata->connected) {
+	/* RvC: DTC3181E has some trouble with this so we simply removed it.
+	 * Seems to work with only Mustek scanner attached.
+	 */
+	if (!(hostdata->flags & FLAG_DTC3181E) &&
+	    ((NCR5380_read(INITIATOR_COMMAND_REG) & ICR_ARBITRATION_LOST) ||
+	     hostdata->connected)) {
 		NCR5380_write(MODE_REG, MR_BASE);
 		NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
 		dprintk(NDEBUG_ARBITRATION, "scsi%d: lost arbitration, deasserting ICR_ASSERT_SEL\n",
Index: linux/drivers/scsi/NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/NCR5380.c	2015-11-18 19:34:04.000000000 +1100
+++ linux/drivers/scsi/NCR5380.c	2015-11-18 19:34:08.000000000 +1100
@@ -1154,11 +1154,10 @@ static int NCR5380_select(struct Scsi_Ho
 	NCR5380_write(INITIATOR_COMMAND_REG,
 		      ICR_BASE | ICR_ASSERT_SEL | ICR_ASSERT_BSY);
 
+	/* RvC: DTC3181E has some trouble with this so we simply removed it.
+	 * Seems to work with only Mustek scanner attached.
+	 */
 	if (!(hostdata->flags & FLAG_DTC3181E) &&
-	    /* RvC: DTC3181E has some trouble with this
-	     *      so we simply removed it. Seems to work with
-	     *      only Mustek scanner attached
-	     */
 	    (NCR5380_read(INITIATOR_COMMAND_REG) & ICR_ARBITRATION_LOST)) {
 		NCR5380_write(MODE_REG, MR_BASE);
 		NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);

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

* [PATCH 50/71] ncr5380: Change instance->host_lock to hostdata->lock
  2015-11-18  8:34 ` Finn Thain
@ 2015-11-18  8:35   ` Finn Thain
  -1 siblings, 0 replies; 268+ messages in thread
From: Finn Thain @ 2015-11-18  8:35 UTC (permalink / raw)
  To: James E.J. Bottomley, Michael Schmitz, linux-m68k, linux-scsi,
	linux-kernel

[-- Attachment #1: ncr5380-adopt-new-spin-lock --]
[-- Type: text/plain, Size: 35013 bytes --]

NCR5380.c presently uses the instance->host_lock spin lock. Convert this
to a new spin lock that protects the NCR5380_hostdata struct.

atari_NCR5380.c previously used local_irq_save/restore() rather than a
spin lock. Convert this to hostdata->lock in irq mode. For SMP platforms,
the interrupt handler now also acquires the spin lock.

This brings all locking in the two core drivers into agreement.

Adding this locking also means that a bunch of volatile qualifiers can be
removed from the members of the NCR5380_hostdata struct. This is done in
a subsequent patch.

Proper locking will allow the abort handler to locate a command being
aborted. This is presently impossible if the abort handler is invoked when
the command has been moved from a queue to a pointer on the stack. (If
eh_abort_handler can't determine whether a command has been completed
or is still being processed then it can't decide whether to return
success or failure.)

The hostdata spin lock is now held when calling NCR5380_select() and
NCR5380_information_transfer(). Where possible, the lock is dropped for
polling and PIO transfers.

Clean up the now-redundant SELECT_ENABLE_REG writes, that used to provide
limited mutual exclusion between information_transfer() and reselect().

Accessing hostdata->connected without data races means taking the lock;
cleanup these accesses.

The new spin lock falls away for m68k and other UP builds, so this should
have little impact there. In the SMP case the new lock should be
uncontested even when the SCSI bus is contested.

Signed-off-by: Finn Thain <fthain@telegraphics.com.au>

---
 drivers/scsi/NCR5380.c       |   83 ++++++++++++++++---------
 drivers/scsi/NCR5380.h       |    1 
 drivers/scsi/atari_NCR5380.c |  139 +++++++++++++++++--------------------------
 3 files changed, 112 insertions(+), 111 deletions(-)

Index: linux/drivers/scsi/NCR5380.h
===================================================================
--- linux.orig/drivers/scsi/NCR5380.h	2015-11-18 19:34:01.000000000 +1100
+++ linux/drivers/scsi/NCR5380.h	2015-11-18 19:34:10.000000000 +1100
@@ -257,6 +257,7 @@ struct NCR5380_hostdata {
 	volatile struct scsi_cmnd *connected;	/* currently connected command */
 	volatile struct scsi_cmnd *issue_queue;	/* waiting to be issued */
 	volatile struct scsi_cmnd *disconnected_queue;	/* waiting for reconnect */
+	spinlock_t lock;			/* protects this struct */
 	int flags;
 	struct scsi_eh_save ses;
 	char info[256];
Index: linux/drivers/scsi/atari_NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/atari_NCR5380.c	2015-11-18 19:34:08.000000000 +1100
+++ linux/drivers/scsi/atari_NCR5380.c	2015-11-18 19:34:10.000000000 +1100
@@ -557,15 +557,13 @@ static struct {
 static void NCR5380_print(struct Scsi_Host *instance)
 {
 	unsigned char status, data, basr, mr, icr, i;
-	unsigned long flags;
 
-	local_irq_save(flags);
 	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);
-	local_irq_restore(flags);
+
 	printk("STATUS_REG: %02x ", status);
 	for (i = 0; signals[i].mask; ++i)
 		if (status & signals[i].mask)
@@ -696,14 +694,12 @@ static void __maybe_unused NCR5380_print
 {
 	struct NCR5380_hostdata *hostdata;
 	struct scsi_cmnd *ptr;
-	unsigned long flags;
 
 	NCR5380_dprint(NDEBUG_ANY, instance);
 	NCR5380_dprint_phase(NDEBUG_ANY, instance);
 
 	hostdata = (struct NCR5380_hostdata *)instance->hostdata;
 
-	local_irq_save(flags);
 	if (!hostdata->connected)
 		printk("scsi%d: no currently connected command\n", HOSTNO);
 	else
@@ -716,8 +712,6 @@ static void __maybe_unused NCR5380_print
 	for (ptr = (struct scsi_cmnd *) hostdata->disconnected_queue; ptr;
 	     ptr = NEXT(ptr))
 		lprint_Scsi_Cmnd(ptr);
-
-	local_irq_restore(flags);
 	printk("\n");
 }
 
@@ -744,7 +738,7 @@ static int __maybe_unused NCR5380_show_i
 
 	hostdata = (struct NCR5380_hostdata *)instance->hostdata;
 
-	local_irq_save(flags);
+	spin_lock_irqsave(&hostdata->lock, flags);
 	if (!hostdata->connected)
 		seq_printf(m, "scsi%d: no currently connected command\n", HOSTNO);
 	else
@@ -758,7 +752,7 @@ static int __maybe_unused NCR5380_show_i
 	     ptr = NEXT(ptr))
 		show_Scsi_Cmnd(ptr, m);
 
-	local_irq_restore(flags);
+	spin_unlock_irqrestore(&hostdata->lock, flags);
 	return 0;
 }
 
@@ -795,6 +789,7 @@ static int __init NCR5380_init(struct Sc
 #if defined (REAL_DMA)
 	hostdata->dma_len = 0;
 #endif
+	spin_lock_init(&hostdata->lock);
 	hostdata->connected = NULL;
 	hostdata->issue_queue = NULL;
 	hostdata->disconnected_queue = NULL;
@@ -943,7 +938,7 @@ static int NCR5380_queue_command(struct
 	if (!NCR5380_acquire_dma_irq(instance))
 		return SCSI_MLQUEUE_HOST_BUSY;
 
-	local_irq_save(flags);
+	spin_lock_irqsave(&hostdata->lock, flags);
 
 	/*
 	 * Insert the cmd into the issue queue. Note that REQUEST SENSE
@@ -963,7 +958,7 @@ static int NCR5380_queue_command(struct
 		LIST(cmd, tmp);
 		SET_NEXT(tmp, cmd);
 	}
-	local_irq_restore(flags);
+	spin_unlock_irqrestore(&hostdata->lock, flags);
 
 	dprintk(NDEBUG_QUEUES, "scsi%d: command added to %s of queue\n", H_NO(cmd),
 		  (cmd->cmnd[0] == REQUEST_SENSE) ? "head" : "tail");
@@ -1003,7 +998,6 @@ static void NCR5380_main(struct work_str
 	struct Scsi_Host *instance = hostdata->host;
 	struct scsi_cmnd *tmp, *prev;
 	int done;
-	unsigned long flags;
 
 	/*
 	 * ++roman: Just disabling the NCR interrupt isn't sufficient here,
@@ -1011,9 +1005,8 @@ static void NCR5380_main(struct work_str
 	 * alter queues and touch the Falcon lock.
 	 */
 
-	local_save_flags(flags);
+	spin_lock_irq(&hostdata->lock);
 	do {
-		local_irq_disable();	/* Freeze request queues */
 		done = 1;
 
 		if (!hostdata->connected) {
@@ -1040,7 +1033,6 @@ static void NCR5380_main(struct work_str
 				        tmp, scmd_id(tmp), hostdata->busy[scmd_id(tmp)],
 				        lun);
 				/*  When we find one, remove it from the issue queue. */
-				/* ++guenther: possible race with Falcon locking */
 				if (
 #ifdef SUPPORT_TAGS
 				    !is_lun_busy( tmp, tmp->cmnd[0] != REQUEST_SENSE)
@@ -1048,8 +1040,6 @@ static void NCR5380_main(struct work_str
 				    !(hostdata->busy[tmp->device->id] & (1 << lun))
 #endif
 				    ) {
-					/* ++guenther: just to be sure, this must be atomic */
-					local_irq_disable();
 					if (prev) {
 						REMOVE(prev, NEXT(prev), tmp, NEXT(tmp));
 						SET_NEXT(prev, NEXT(tmp));
@@ -1060,9 +1050,6 @@ static void NCR5380_main(struct work_str
 					SET_NEXT(tmp, NULL);
 					hostdata->retain_dma_intr++;
 
-					/* reenable interrupts after finding one */
-					local_irq_restore(flags);
-
 					/*
 					 * Attempt to establish an I_T_L nexus here.
 					 * On success, instance->hostdata->connected is set.
@@ -1087,13 +1074,10 @@ static void NCR5380_main(struct work_str
 #endif
 					if (!NCR5380_select(instance, tmp)) {
 						/* OK or bad target */
-						local_irq_disable();
 						hostdata->retain_dma_intr--;
 						maybe_release_dma_irq(instance);
-						local_irq_restore(flags);
 					} else {
 						/* Need to retry */
-						local_irq_disable();
 						LIST(tmp, hostdata->issue_queue);
 						SET_NEXT(tmp, hostdata->issue_queue);
 						hostdata->issue_queue = tmp;
@@ -1101,7 +1085,6 @@ static void NCR5380_main(struct work_str
 						cmd_free_tag(tmp);
 #endif
 						hostdata->retain_dma_intr--;
-						local_irq_restore(flags);
 						done = 0;
 						dprintk(NDEBUG_MAIN, "scsi%d: main(): select() failed, "
 							    "returned to issue_queue\n", HOSTNO);
@@ -1117,7 +1100,6 @@ static void NCR5380_main(struct work_str
 		    && !hostdata->dma_len
 #endif
 		    ) {
-			local_irq_restore(flags);
 			dprintk(NDEBUG_MAIN, "scsi%d: main: performing information transfer\n",
 				    HOSTNO);
 			NCR5380_information_transfer(instance);
@@ -1125,7 +1107,7 @@ static void NCR5380_main(struct work_str
 			done = 0;
 		}
 	} while (!done);
-	local_irq_restore(flags);
+	spin_unlock_irq(&hostdata->lock);
 }
 
 
@@ -1254,6 +1236,9 @@ static irqreturn_t NCR5380_intr(int irq,
 	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) {
@@ -1313,6 +1298,8 @@ static irqreturn_t NCR5380_intr(int irq,
 #endif
 	}
 
+	spin_unlock_irqrestore(&hostdata->lock, flags);
+
 	return IRQ_RETVAL(handled);
 }
 
@@ -1352,7 +1339,6 @@ static int NCR5380_select(struct Scsi_Ho
 	unsigned char *data;
 	int len;
 	int err;
-	unsigned long flags;
 
 	NCR5380_dprint(NDEBUG_ARBITRATION, instance);
 	dprintk(NDEBUG_ARBITRATION, "scsi%d: starting arbitration, id = %d\n", HOSTNO,
@@ -1363,11 +1349,6 @@ static int NCR5380_select(struct Scsi_Ho
 	 * data bus during SELECTION.
 	 */
 
-	local_irq_save(flags);
-	if (hostdata->connected) {
-		local_irq_restore(flags);
-		return -1;
-	}
 	NCR5380_write(TARGET_COMMAND_REG, 0);
 
 	/*
@@ -1381,10 +1362,11 @@ static int NCR5380_select(struct Scsi_Ho
 	 * Bus Free Delay, arbitration will begin.
 	 */
 
-	local_irq_restore(flags);
+	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 */
 		return -1;
@@ -1395,6 +1377,7 @@ static int NCR5380_select(struct Scsi_Ho
 		             "select: arbitration timeout\n");
 		return -1;
 	}
+	spin_unlock_irq(&hostdata->lock);
 
 	/* The SCSI-2 arbitration delay is 2.4 us */
 	udelay(3);
@@ -1402,11 +1385,11 @@ static int NCR5380_select(struct Scsi_Ho
 	/* 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) ||
-	    hostdata->connected) {
+	    (NCR5380_read(INITIATOR_COMMAND_REG) & ICR_ARBITRATION_LOST)) {
 		NCR5380_write(MODE_REG, MR_BASE);
 		dprintk(NDEBUG_ARBITRATION, "scsi%d: lost arbitration, deasserting MR_ARBITRATE\n",
 			   HOSTNO);
+		spin_lock_irq(&hostdata->lock);
 		return -1;
 	}
 
@@ -1421,12 +1404,12 @@ static int NCR5380_select(struct Scsi_Ho
 	 * Seems to work with only Mustek scanner attached.
 	 */
 	if (!(hostdata->flags & FLAG_DTC3181E) &&
-	    ((NCR5380_read(INITIATOR_COMMAND_REG) & ICR_ARBITRATION_LOST) ||
-	     hostdata->connected)) {
+	    (NCR5380_read(INITIATOR_COMMAND_REG) & ICR_ARBITRATION_LOST)) {
 		NCR5380_write(MODE_REG, MR_BASE);
 		NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
 		dprintk(NDEBUG_ARBITRATION, "scsi%d: lost arbitration, deasserting ICR_ASSERT_SEL\n",
 			   HOSTNO);
+		spin_lock_irq(&hostdata->lock);
 		return -1;
 	}
 
@@ -1440,6 +1423,8 @@ static int NCR5380_select(struct Scsi_Ho
 	else
 		udelay(2);
 
+	spin_lock_irq(&hostdata->lock);
+
 	/* NCR5380_reselect() clears MODE_REG after a reselection interrupt */
 	if (!(NCR5380_read(MODE_REG) & MR_ARBITRATE))
 		return -1;
@@ -1467,14 +1452,10 @@ static int NCR5380_select(struct Scsi_Ho
 	 * Reselect interrupts must be turned off prior to the dropping of BSY,
 	 * otherwise we will trigger an interrupt.
 	 */
-
-	if (hostdata->connected) {
-		NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
-		return -1;
-	}
-
 	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.
@@ -1515,6 +1496,7 @@ static int NCR5380_select(struct Scsi_Ho
 	                            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)
@@ -1525,6 +1507,7 @@ static int NCR5380_select(struct Scsi_Ho
 	}
 
 	if (err < 0) {
+		spin_lock_irq(&hostdata->lock);
 		NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
 		cmd->result = DID_BAD_TARGET << 16;
 #ifdef SUPPORT_TAGS
@@ -1564,6 +1547,7 @@ static int NCR5380_select(struct Scsi_Ho
 	/* 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);
@@ -1593,6 +1577,7 @@ static int NCR5380_select(struct Scsi_Ho
 	NCR5380_transfer_pio(instance, &phase, &len, &data);
 	dprintk(NDEBUG_SELECTION, "scsi%d: nexus established.\n", HOSTNO);
 	/* XXX need to handle errors here */
+
 	hostdata->connected = cmd;
 #ifndef SUPPORT_TAGS
 	hostdata->busy[cmd->device->id] |= (1 << cmd->device->lun);
@@ -1859,7 +1844,6 @@ static int NCR5380_transfer_dma(struct S
 	SETUP_HOSTDATA(instance);
 	register int c = *count;
 	register unsigned char p = *phase;
-	unsigned long flags;
 
 #if defined(CONFIG_SUN3)
 	/* sanity check */
@@ -1875,7 +1859,6 @@ static int NCR5380_transfer_dma(struct S
 		c, (p & SR_IO) ? "to" : "from", *data);
 
 	/* netbsd turns off ints here, why not be safe and do it too */
-	local_irq_save(flags);
 
 	/* send start chain */
 	sun3scsi_dma_start(c, *data);
@@ -1895,8 +1878,6 @@ static int NCR5380_transfer_dma(struct S
 	dregs->csr |= CSR_DMA_ENABLE;
 #endif
 
-	local_irq_restore(flags);
-
 	sun3_dma_active = 1;
 
 #else /* !defined(CONFIG_SUN3) */
@@ -1923,11 +1904,9 @@ static int NCR5380_transfer_dma(struct S
 		/* On the Medusa, it is a must to initialize the DMA before
 		 * starting the NCR. This is also the cleaner way for the TT.
 		 */
-		local_irq_save(flags);
 		hostdata->dma_len = (p & SR_IO) ?
 			NCR5380_dma_read_setup(instance, d, c) :
 			NCR5380_dma_write_setup(instance, d, c);
-		local_irq_restore(flags);
 	}
 
 	if (p & SR_IO)
@@ -1941,11 +1920,9 @@ static int NCR5380_transfer_dma(struct S
 		/* On the Falcon, the DMA setup must be done after the last */
 		/* NCR access, else the DMA setup gets trashed!
 		 */
-		local_irq_save(flags);
 		hostdata->dma_len = (p & SR_IO) ?
 			NCR5380_dma_read_setup(instance, d, c) :
 			NCR5380_dma_write_setup(instance, d, c);
-		local_irq_restore(flags);
 	}
 #endif /* !defined(CONFIG_SUN3) */
 
@@ -1973,7 +1950,6 @@ static int NCR5380_transfer_dma(struct S
 static void NCR5380_information_transfer(struct Scsi_Host *instance)
 {
 	SETUP_HOSTDATA(instance);
-	unsigned long flags;
 	unsigned char msgout = NOP;
 	int sink = 0;
 	int len;
@@ -1982,13 +1958,13 @@ static void NCR5380_information_transfer
 #endif
 	unsigned char *data;
 	unsigned char phase, tmp, extended_msg[10], old_phase = 0xff;
-	struct scsi_cmnd *cmd = (struct scsi_cmnd *) hostdata->connected;
+	struct scsi_cmnd *cmd;
 
 #ifdef SUN3_SCSI_VME
 	dregs->csr |= CSR_INTR;
 #endif
 
-	while (1) {
+	while ((cmd = hostdata->connected)) {
 		tmp = NCR5380_read(STATUS_REG);
 		/* We only have a valid SCSI phase when REQ is asserted */
 		if (tmp & SR_REQ) {
@@ -2122,9 +2098,13 @@ static void NCR5380_information_transfer
 					}
 				} else
 #endif /* defined(REAL_DMA) */
+				{
+					spin_unlock_irq(&hostdata->lock);
 					NCR5380_transfer_pio(instance, &phase,
 							     (int *)&cmd->SCp.this_residual,
 							     (unsigned char **)&cmd->SCp.ptr);
+					spin_lock_irq(&hostdata->lock);
+				}
 #if defined(CONFIG_SUN3) && defined(REAL_DMA)
 				/* if we had intended to dma that command clear it */
 				if (sun3_dma_setup_done == cmd)
@@ -2134,7 +2114,6 @@ static void NCR5380_information_transfer
 			case PHASE_MSGIN:
 				len = 1;
 				data = &tmp;
-				NCR5380_write(SELECT_ENABLE_REG, 0);	/* disable reselects */
 				NCR5380_transfer_pio(instance, &phase, &len, &data);
 				cmd->SCp.Message = tmp;
 
@@ -2146,7 +2125,6 @@ static void NCR5380_information_transfer
 					dprintk(NDEBUG_QUEUES, "scsi%d: command for target %d, lun %llu "
 						  "completed\n", HOSTNO, cmd->device->id, cmd->device->lun);
 
-					local_irq_save(flags);
 					hostdata->connected = NULL;
 #ifdef SUPPORT_TAGS
 					cmd_free_tag(cmd);
@@ -2162,8 +2140,6 @@ static void NCR5380_information_transfer
 #else
 					hostdata->busy[cmd->device->id] &= ~(1 << cmd->device->lun);
 #endif
-					/* Enable reselect interrupts */
-					NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
 
 					/*
 					 * I'm not sure what the correct thing to do here is :
@@ -2221,13 +2197,10 @@ static void NCR5380_information_transfer
 					 * disconnected queue.
 					 */
 					maybe_release_dma_irq(instance);
-					local_irq_restore(flags);
 					return;
 				case MESSAGE_REJECT:
 					/* Accept message by clearing ACK */
 					NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
-					/* Enable reselect interrupts */
-					NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
 					switch (hostdata->last_message) {
 					case HEAD_OF_QUEUE_TAG:
 					case ORDERED_QUEUE_TAG:
@@ -2251,12 +2224,10 @@ static void NCR5380_information_transfer
 				case DISCONNECT:
 					/* Accept message by clearing ACK */
 					NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
-					local_irq_save(flags);
 					LIST(cmd,hostdata->disconnected_queue);
 					SET_NEXT(cmd, hostdata->disconnected_queue);
 					hostdata->connected = NULL;
 					hostdata->disconnected_queue = cmd;
-					local_irq_restore(flags);
 					dprintk(NDEBUG_QUEUES, "scsi%d: command for target %d lun %llu was "
 						  "moved from connected to the "
 						  "disconnected_queue\n", HOSTNO,
@@ -2287,8 +2258,6 @@ static void NCR5380_information_transfer
 				case RESTORE_POINTERS:
 					/* Accept message by clearing ACK */
 					NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
-					/* Enable reselect interrupts */
-					NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
 					break;
 				case EXTENDED_MESSAGE:
 					/*
@@ -2307,6 +2276,8 @@ static void NCR5380_information_transfer
 					/* Accept first byte by clearing ACK */
 					NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
 
+					spin_unlock_irq(&hostdata->lock);
+
 					dprintk(NDEBUG_EXTENDED, "scsi%d: receiving extended message\n", HOSTNO);
 
 					len = 2;
@@ -2345,6 +2316,11 @@ static void NCR5380_information_transfer
 							   HOSTNO, extended_msg[2], extended_msg[1]);
 						tmp = 0;
 					}
+
+					spin_lock_irq(&hostdata->lock);
+					if (!hostdata->connected)
+						return;
+
 					/* Fall through to reject message */
 
 					/*
@@ -2377,7 +2353,6 @@ static void NCR5380_information_transfer
 				hostdata->last_message = msgout;
 				NCR5380_transfer_pio(instance, &phase, &len, &data);
 				if (msgout == ABORT) {
-					local_irq_save(flags);
 #ifdef SUPPORT_TAGS
 					cmd_free_tag(cmd);
 #else
@@ -2386,7 +2361,6 @@ static void NCR5380_information_transfer
 					hostdata->connected = NULL;
 					cmd->result = DID_ERROR << 16;
 					maybe_release_dma_irq(instance);
-					local_irq_restore(flags);
 					cmd->scsi_done(cmd);
 					NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
 					return;
@@ -2414,9 +2388,11 @@ static void NCR5380_information_transfer
 				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);
 		}
-	} /* while (1) */
+	}
 }
 
 /*
@@ -2649,9 +2625,9 @@ int NCR5380_abort(struct scsi_cmnd *cmd)
 
 	scmd_printk(KERN_NOTICE, cmd, "aborting command\n");
 
-	NCR5380_print_status(instance);
+	spin_lock_irqsave(&hostdata->lock, flags);
 
-	local_irq_save(flags);
+	NCR5380_print_status(instance);
 
 	dprintk(NDEBUG_ABORT, "scsi%d: abort called basr 0x%02x, sr 0x%02x\n", HOSTNO,
 		    NCR5380_read(BUS_AND_STATUS_REG),
@@ -2693,11 +2669,11 @@ int NCR5380_abort(struct scsi_cmnd *cmd)
 			hostdata->busy[cmd->device->id] &= ~(1 << cmd->device->lun);
 #endif
 			maybe_release_dma_irq(instance);
-			local_irq_restore(flags);
+			spin_unlock_irqrestore(&hostdata->lock, flags);
 			cmd->scsi_done(cmd);
 			return SUCCESS;
 		} else {
-			local_irq_restore(flags);
+			spin_unlock_irqrestore(&hostdata->lock, flags);
 			printk("scsi%d: abort of connected command failed!\n", HOSTNO);
 			return FAILED;
 		}
@@ -2717,7 +2693,7 @@ int NCR5380_abort(struct scsi_cmnd *cmd)
 			SET_NEXT(tmp, NULL);
 			tmp->result = DID_ABORT << 16;
 			maybe_release_dma_irq(instance);
-			local_irq_restore(flags);
+			spin_unlock_irqrestore(&hostdata->lock, flags);
 			dprintk(NDEBUG_ABORT, "scsi%d: abort removed command from issue queue.\n",
 				    HOSTNO);
 			/* Tagged queuing note: no tag to free here, hasn't been assigned
@@ -2739,7 +2715,7 @@ int NCR5380_abort(struct scsi_cmnd *cmd)
 	 */
 
 	if (hostdata->connected) {
-		local_irq_restore(flags);
+		spin_unlock_irqrestore(&hostdata->lock, flags);
 		dprintk(NDEBUG_ABORT, "scsi%d: abort failed, command connected.\n", HOSTNO);
 		return FAILED;
 	}
@@ -2772,17 +2748,16 @@ int NCR5380_abort(struct scsi_cmnd *cmd)
 	for (tmp = (struct scsi_cmnd *) hostdata->disconnected_queue; tmp;
 	     tmp = NEXT(tmp)) {
 		if (cmd == tmp) {
-			local_irq_restore(flags);
 			dprintk(NDEBUG_ABORT, "scsi%d: aborting disconnected command.\n", HOSTNO);
 
-			if (NCR5380_select(instance, cmd))
+			if (NCR5380_select(instance, cmd)) {
+				spin_unlock_irq(&hostdata->lock);
 				return FAILED;
-
+			}
 			dprintk(NDEBUG_ABORT, "scsi%d: nexus reestablished.\n", HOSTNO);
 
 			do_abort(instance);
 
-			local_irq_save(flags);
 			for (prev = (struct scsi_cmnd **)&(hostdata->disconnected_queue),
 			     tmp = (struct scsi_cmnd *)hostdata->disconnected_queue;
 			     tmp; prev = NEXTADDR(tmp), tmp = NEXT(tmp)) {
@@ -2801,7 +2776,7 @@ int NCR5380_abort(struct scsi_cmnd *cmd)
 					hostdata->busy[cmd->device->id] &= ~(1 << cmd->device->lun);
 #endif
 					maybe_release_dma_irq(instance);
-					local_irq_restore(flags);
+					spin_unlock_irqrestore(&hostdata->lock, flags);
 					tmp->scsi_done(tmp);
 					return SUCCESS;
 				}
@@ -2814,7 +2789,7 @@ int NCR5380_abort(struct scsi_cmnd *cmd)
 	 * released after the abort, in case it is kept due to some bug.
 	 */
 	maybe_release_dma_irq(instance);
-	local_irq_restore(flags);
+	spin_unlock_irqrestore(&hostdata->lock, flags);
 
 	/*
 	 * Case 5 : If we reached this point, the command was not found in any of
@@ -2846,7 +2821,7 @@ static int NCR5380_bus_reset(struct scsi
 	int i;
 	unsigned long flags;
 
-	local_irq_save(flags);
+	spin_lock_irqsave(&hostdata->lock, flags);
 
 #if (NDEBUG & NDEBUG_ANY)
 	scmd_printk(KERN_INFO, cmd, "performing bus reset\n");
@@ -2886,7 +2861,7 @@ static int NCR5380_bus_reset(struct scsi
 #endif
 
 	maybe_release_dma_irq(instance);
-	local_irq_restore(flags);
+	spin_unlock_irqrestore(&hostdata->lock, flags);
 
 	return SUCCESS;
 }
Index: linux/drivers/scsi/NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/NCR5380.c	2015-11-18 19:34:08.000000000 +1100
+++ linux/drivers/scsi/NCR5380.c	2015-11-18 19:34:10.000000000 +1100
@@ -624,6 +624,7 @@ static int __maybe_unused NCR5380_show_i
 {
 	struct NCR5380_hostdata *hostdata;
 	struct scsi_cmnd *ptr;
+	unsigned long flags;
 
 	hostdata = (struct NCR5380_hostdata *) instance->hostdata;
 
@@ -631,7 +632,7 @@ static int __maybe_unused NCR5380_show_i
 	seq_printf(m, "Highwater I/O busy spin counts: write %d, read %d\n",
 	        hostdata->spin_max_w, hostdata->spin_max_r);
 #endif
-	spin_lock_irq(instance->host_lock);
+	spin_lock_irqsave(&hostdata->lock, flags);
 	if (!hostdata->connected)
 		seq_printf(m, "scsi%d: no currently connected command\n", instance->host_no);
 	else
@@ -643,7 +644,7 @@ static int __maybe_unused NCR5380_show_i
 	seq_printf(m, "scsi%d: disconnected_queue\n", instance->host_no);
 	for (ptr = (struct scsi_cmnd *) hostdata->disconnected_queue; ptr; ptr = (struct scsi_cmnd *) ptr->host_scribble)
 		lprint_Scsi_Cmnd(ptr, m);
-	spin_unlock_irq(instance->host_lock);
+	spin_unlock_irqrestore(&hostdata->lock, flags);
 	return 0;
 }
 
@@ -702,6 +703,7 @@ static int NCR5380_init(struct Scsi_Host
 #ifdef REAL_DMA
 	hostdata->dmalen = 0;
 #endif
+	spin_lock_init(&hostdata->lock);
 	hostdata->connected = NULL;
 	hostdata->issue_queue = NULL;
 	hostdata->disconnected_queue = NULL;
@@ -826,7 +828,7 @@ static int NCR5380_queue_command(struct
 	cmd->host_scribble = NULL;
 	cmd->result = 0;
 
-	spin_lock_irqsave(instance->host_lock, flags);
+	spin_lock_irqsave(&hostdata->lock, flags);
 
 	/* 
 	 * Insert the cmd into the issue queue. Note that REQUEST SENSE 
@@ -844,7 +846,7 @@ static int NCR5380_queue_command(struct
 		LIST(cmd, tmp);
 		tmp->host_scribble = (unsigned char *) cmd;
 	}
-	spin_unlock_irqrestore(instance->host_lock, flags);
+	spin_unlock_irqrestore(&hostdata->lock, flags);
 
 	dprintk(NDEBUG_QUEUES, "scsi%d : command added to %s of queue\n", instance->host_no, (cmd->cmnd[0] == REQUEST_SENSE) ? "head" : "tail");
 
@@ -873,10 +875,10 @@ static void NCR5380_main(struct work_str
 	struct scsi_cmnd *tmp, *prev;
 	int done;
 	
-	spin_lock_irq(instance->host_lock);
+	spin_lock_irq(&hostdata->lock);
 	do {
-		/* Lock held here */
 		done = 1;
+
 		if (!hostdata->connected) {
 			dprintk(NDEBUG_MAIN, "scsi%d : not connected\n", instance->host_no);
 			/*
@@ -926,11 +928,10 @@ static void NCR5380_main(struct work_str
 					}
 					if (hostdata->connected)
 						break;
-					/* lock held here still */
 				}	/* if target/lun is not busy */
 			}	/* for */
-			/* exited locked */
 		}	/* if (!hostdata->connected) */
+
 		if (hostdata->connected
 #ifdef REAL_DMA
 		    && !hostdata->dmalen
@@ -942,8 +943,7 @@ static void NCR5380_main(struct work_str
 			done = 0;
 		}
 	} while (!done);
-	
-	spin_unlock_irq(instance->host_lock);
+	spin_unlock_irq(&hostdata->lock);
 }
 
 #ifndef DONT_USE_INTR
@@ -990,7 +990,7 @@ static irqreturn_t NCR5380_intr(int irq,
 	unsigned char basr;
 	unsigned long flags;
 
-	spin_lock_irqsave(instance->host_lock, flags);
+	spin_lock_irqsave(&hostdata->lock, flags);
 
 	basr = NCR5380_read(BUS_AND_STATUS_REG);
 	if (basr & BASR_IRQ) {
@@ -1054,7 +1054,7 @@ static irqreturn_t NCR5380_intr(int irq,
 		shost_printk(KERN_NOTICE, instance, "interrupt without IRQ bit\n");
 	}
 
-	spin_unlock_irqrestore(instance->host_lock, flags);
+	spin_unlock_irqrestore(&hostdata->lock, flags);
 
 	return IRQ_RETVAL(handled);
 }
@@ -1121,11 +1121,11 @@ static int NCR5380_select(struct Scsi_Ho
 	 * Bus Free Delay, arbitration will begin.
 	 */
 
-	spin_unlock_irq(instance->host_lock);
+	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(instance->host_lock);
+	spin_lock_irq(&hostdata->lock);
 	if (!(NCR5380_read(MODE_REG) & MR_ARBITRATE)) {
 		/* Reselection interrupt */
 		return -1;
@@ -1136,6 +1136,7 @@ static int NCR5380_select(struct Scsi_Ho
 		             "select: arbitration timeout\n");
 		return -1;
 	}
+	spin_unlock_irq(&hostdata->lock);
 
 	/* The SCSI-2 arbitration delay is 2.4 us */
 	udelay(3);
@@ -1144,6 +1145,7 @@ static int NCR5380_select(struct Scsi_Ho
 	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);
 		dprintk(NDEBUG_ARBITRATION, "scsi%d : lost arbitration, deasserting MR_ARBITRATE\n", instance->host_no);
+		spin_lock_irq(&hostdata->lock);
 		return -1;
 	}
 
@@ -1162,6 +1164,7 @@ static int NCR5380_select(struct Scsi_Ho
 		NCR5380_write(MODE_REG, MR_BASE);
 		NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
 		dprintk(NDEBUG_ARBITRATION, "scsi%d : lost arbitration, deasserting ICR_ASSERT_SEL\n", instance->host_no);
+		spin_lock_irq(&hostdata->lock);
 		return -1;
 	}
 	/* 
@@ -1174,6 +1177,8 @@ static int NCR5380_select(struct Scsi_Ho
 	else
 		udelay(2);
 
+	spin_lock_irq(&hostdata->lock);
+
 	/* NCR5380_reselect() clears MODE_REG after a reselection interrupt */
 	if (!(NCR5380_read(MODE_REG) & MR_ARBITRATE))
 		return -1;
@@ -1202,6 +1207,8 @@ static int NCR5380_select(struct Scsi_Ho
 	 */
 	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.
@@ -1241,6 +1248,7 @@ static int NCR5380_select(struct Scsi_Ho
 	                            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)
@@ -1250,6 +1258,7 @@ static int NCR5380_select(struct Scsi_Ho
 	}
 
 	if (err < 0) {
+		spin_lock_irq(&hostdata->lock);
 		NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
 		cmd->result = DID_BAD_TARGET << 16;
 		cmd->scsi_done(cmd);
@@ -1286,9 +1295,8 @@ static int NCR5380_select(struct Scsi_Ho
 
 	/* Wait for start of REQ/ACK handshake */
 
-	spin_unlock_irq(instance->host_lock);
 	err = NCR5380_poll_politely(instance, STATUS_REG, SR_REQ, SR_REQ, HZ);
-	spin_lock_irq(instance->host_lock);
+	spin_lock_irq(&hostdata->lock);
 	if (err < 0) {
 		shost_printk(KERN_ERR, instance, "select: REQ timeout\n");
 		NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
@@ -1308,6 +1316,7 @@ static int NCR5380_select(struct Scsi_Ho
 	NCR5380_transfer_pio(instance, &phase, &len, &data);
 	dprintk(NDEBUG_SELECTION, "scsi%d : nexus established.\n", instance->host_no);
 	/* XXX need to handle errors here */
+
 	hostdata->connected = cmd;
 	hostdata->busy[cmd->device->id] |= (1 << (cmd->device->lun & 0xFF));
 
@@ -1811,9 +1820,9 @@ static void NCR5380_information_transfer
 #endif
 	unsigned char *data;
 	unsigned char phase, tmp, extended_msg[10], old_phase = 0xff;
-	struct scsi_cmnd *cmd = (struct scsi_cmnd *) hostdata->connected;
+	struct scsi_cmnd *cmd;
 
-	while (1) {
+	while ((cmd = hostdata->connected)) {
 		tmp = NCR5380_read(STATUS_REG);
 		/* We only have a valid SCSI phase when REQ is asserted */
 		if (tmp & SR_REQ) {
@@ -1889,8 +1898,12 @@ static void NCR5380_information_transfer
 						cmd->SCp.this_residual -= transfersize - len;
 				} else
 #endif				/* defined(PSEUDO_DMA) || defined(REAL_DMA_POLL) */
+				{
+					spin_unlock_irq(&hostdata->lock);
 					NCR5380_transfer_pio(instance, &phase, (int *) &cmd->SCp.this_residual, (unsigned char **)
 							     &cmd->SCp.ptr);
+					spin_lock_irq(&hostdata->lock);
+				}
 				break;
 			case PHASE_MSGIN:
 				len = 1;
@@ -2022,6 +2035,9 @@ static void NCR5380_information_transfer
 					extended_msg[0] = EXTENDED_MESSAGE;
 					/* Accept first byte by clearing ACK */
 					NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
+
+					spin_unlock_irq(&hostdata->lock);
+
 					dprintk(NDEBUG_EXTENDED, "scsi%d : receiving extended message\n", instance->host_no);
 
 					len = 2;
@@ -2056,6 +2072,11 @@ static void NCR5380_information_transfer
 						printk("scsi%d: extended message code %02x length %d is too long\n", instance->host_no, extended_msg[2], extended_msg[1]);
 						tmp = 0;
 					}
+
+					spin_lock_irq(&hostdata->lock);
+					if (!hostdata->connected)
+						return;
+
 					/* Fall through to reject message */
 
 					/* 
@@ -2115,11 +2136,11 @@ static void NCR5380_information_transfer
 				NCR5380_dprint(NDEBUG_ANY, instance);
 			}	/* switch(phase) */
 		} else {
-			spin_unlock_irq(instance->host_lock);
+			spin_unlock_irq(&hostdata->lock);
 			NCR5380_poll_politely(instance, STATUS_REG, SR_REQ, SR_REQ, HZ);
-			spin_lock_irq(instance->host_lock);
+			spin_lock_irq(&hostdata->lock);
 		}
-	}			/* while (1) */
+	}
 }
 
 /*
@@ -2315,10 +2336,12 @@ static int NCR5380_abort(struct scsi_cmn
 	struct Scsi_Host *instance = cmd->device->host;
 	struct NCR5380_hostdata *hostdata = (struct NCR5380_hostdata *) instance->hostdata;
 	struct scsi_cmnd *tmp, **prev;
+	unsigned long flags;
 
 	scmd_printk(KERN_WARNING, cmd, "aborting command\n");
 
-	spin_lock_irq(instance->host_lock);
+	spin_lock_irqsave(&hostdata->lock, flags);
+
 	NCR5380_print_status(instance);
 
 	dprintk(NDEBUG_ABORT, "scsi%d : abort called\n", instance->host_no);
@@ -2365,7 +2388,7 @@ static int NCR5380_abort(struct scsi_cmn
 			REMOVE(5, *prev, tmp, tmp->host_scribble);
 			(*prev) = (struct scsi_cmnd *) tmp->host_scribble;
 			tmp->host_scribble = NULL;
-			spin_unlock_irq(instance->host_lock);
+			spin_unlock_irqrestore(&hostdata->lock, flags);
 			tmp->result = DID_ABORT << 16;
 			dprintk(NDEBUG_ABORT, "scsi%d : abort removed command from issue queue.\n", instance->host_no);
 			tmp->scsi_done(tmp);
@@ -2389,7 +2412,7 @@ static int NCR5380_abort(struct scsi_cmn
  */
 
 	if (hostdata->connected) {
-		spin_unlock_irq(instance->host_lock);
+		spin_unlock_irqrestore(&hostdata->lock, flags);
 		dprintk(NDEBUG_ABORT, "scsi%d : abort failed, command connected.\n", instance->host_no);
 		return FAILED;
 	}
@@ -2423,7 +2446,7 @@ static int NCR5380_abort(struct scsi_cmn
 			dprintk(NDEBUG_ABORT, "scsi%d : aborting disconnected command.\n", instance->host_no);
 
 			if (NCR5380_select(instance, cmd)) {
-				spin_unlock_irq(instance->host_lock);
+				spin_unlock_irq(&hostdata->lock);
 				return FAILED;
 			}
 			dprintk(NDEBUG_ABORT, "scsi%d : nexus reestablished.\n", instance->host_no);
@@ -2435,7 +2458,7 @@ static int NCR5380_abort(struct scsi_cmn
 					REMOVE(5, *prev, tmp, tmp->host_scribble);
 					*prev = (struct scsi_cmnd *) tmp->host_scribble;
 					tmp->host_scribble = NULL;
-					spin_unlock_irq(instance->host_lock);
+					spin_unlock_irqrestore(&hostdata->lock, flags);
 					tmp->result = DID_ABORT << 16;
 					tmp->scsi_done(tmp);
 					return SUCCESS;
@@ -2450,7 +2473,7 @@ static int NCR5380_abort(struct scsi_cmn
  * so we won't panic, but we will notify the user in case something really
  * broke.
  */
-	spin_unlock_irq(instance->host_lock);
+	spin_unlock_irqrestore(&hostdata->lock, flags);
 	printk(KERN_WARNING "scsi%d : warning : SCSI command probably completed successfully\n"
 			"         before abortion\n", instance->host_no);
 	return FAILED;
@@ -2467,8 +2490,10 @@ static int NCR5380_abort(struct scsi_cmn
 static int NCR5380_bus_reset(struct scsi_cmnd *cmd)
 {
 	struct Scsi_Host *instance = cmd->device->host;
+	struct NCR5380_hostdata *hostdata = shost_priv(instance);
+	unsigned long flags;
 
-	spin_lock_irq(instance->host_lock);
+	spin_lock_irqsave(&hostdata->lock, flags);
 
 #if (NDEBUG & NDEBUG_ANY)
 	scmd_printk(KERN_INFO, cmd, "performing bus reset\n");
@@ -2477,7 +2502,7 @@ static int NCR5380_bus_reset(struct scsi
 
 	do_reset(instance);
 
-	spin_unlock_irq(instance->host_lock);
+	spin_unlock_irqrestore(&hostdata->lock, flags);
 
 	return SUCCESS;
 }



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

* [PATCH 50/71] ncr5380: Change instance->host_lock to hostdata->lock
@ 2015-11-18  8:35   ` Finn Thain
  0 siblings, 0 replies; 268+ messages in thread
From: Finn Thain @ 2015-11-18  8:35 UTC (permalink / raw)
  To: James E.J. Bottomley, Michael Schmitz, linux-m68k, linux-scsi,
	linux-kernel

[-- Attachment #1: ncr5380-adopt-new-spin-lock --]
[-- Type: text/plain, Size: 35011 bytes --]

NCR5380.c presently uses the instance->host_lock spin lock. Convert this
to a new spin lock that protects the NCR5380_hostdata struct.

atari_NCR5380.c previously used local_irq_save/restore() rather than a
spin lock. Convert this to hostdata->lock in irq mode. For SMP platforms,
the interrupt handler now also acquires the spin lock.

This brings all locking in the two core drivers into agreement.

Adding this locking also means that a bunch of volatile qualifiers can be
removed from the members of the NCR5380_hostdata struct. This is done in
a subsequent patch.

Proper locking will allow the abort handler to locate a command being
aborted. This is presently impossible if the abort handler is invoked when
the command has been moved from a queue to a pointer on the stack. (If
eh_abort_handler can't determine whether a command has been completed
or is still being processed then it can't decide whether to return
success or failure.)

The hostdata spin lock is now held when calling NCR5380_select() and
NCR5380_information_transfer(). Where possible, the lock is dropped for
polling and PIO transfers.

Clean up the now-redundant SELECT_ENABLE_REG writes, that used to provide
limited mutual exclusion between information_transfer() and reselect().

Accessing hostdata->connected without data races means taking the lock;
cleanup these accesses.

The new spin lock falls away for m68k and other UP builds, so this should
have little impact there. In the SMP case the new lock should be
uncontested even when the SCSI bus is contested.

Signed-off-by: Finn Thain <fthain@telegraphics.com.au>

---
 drivers/scsi/NCR5380.c       |   83 ++++++++++++++++---------
 drivers/scsi/NCR5380.h       |    1 
 drivers/scsi/atari_NCR5380.c |  139 +++++++++++++++++--------------------------
 3 files changed, 112 insertions(+), 111 deletions(-)

Index: linux/drivers/scsi/NCR5380.h
===================================================================
--- linux.orig/drivers/scsi/NCR5380.h	2015-11-18 19:34:01.000000000 +1100
+++ linux/drivers/scsi/NCR5380.h	2015-11-18 19:34:10.000000000 +1100
@@ -257,6 +257,7 @@ struct NCR5380_hostdata {
 	volatile struct scsi_cmnd *connected;	/* currently connected command */
 	volatile struct scsi_cmnd *issue_queue;	/* waiting to be issued */
 	volatile struct scsi_cmnd *disconnected_queue;	/* waiting for reconnect */
+	spinlock_t lock;			/* protects this struct */
 	int flags;
 	struct scsi_eh_save ses;
 	char info[256];
Index: linux/drivers/scsi/atari_NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/atari_NCR5380.c	2015-11-18 19:34:08.000000000 +1100
+++ linux/drivers/scsi/atari_NCR5380.c	2015-11-18 19:34:10.000000000 +1100
@@ -557,15 +557,13 @@ static struct {
 static void NCR5380_print(struct Scsi_Host *instance)
 {
 	unsigned char status, data, basr, mr, icr, i;
-	unsigned long flags;
 
-	local_irq_save(flags);
 	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);
-	local_irq_restore(flags);
+
 	printk("STATUS_REG: %02x ", status);
 	for (i = 0; signals[i].mask; ++i)
 		if (status & signals[i].mask)
@@ -696,14 +694,12 @@ static void __maybe_unused NCR5380_print
 {
 	struct NCR5380_hostdata *hostdata;
 	struct scsi_cmnd *ptr;
-	unsigned long flags;
 
 	NCR5380_dprint(NDEBUG_ANY, instance);
 	NCR5380_dprint_phase(NDEBUG_ANY, instance);
 
 	hostdata = (struct NCR5380_hostdata *)instance->hostdata;
 
-	local_irq_save(flags);
 	if (!hostdata->connected)
 		printk("scsi%d: no currently connected command\n", HOSTNO);
 	else
@@ -716,8 +712,6 @@ static void __maybe_unused NCR5380_print
 	for (ptr = (struct scsi_cmnd *) hostdata->disconnected_queue; ptr;
 	     ptr = NEXT(ptr))
 		lprint_Scsi_Cmnd(ptr);
-
-	local_irq_restore(flags);
 	printk("\n");
 }
 
@@ -744,7 +738,7 @@ static int __maybe_unused NCR5380_show_i
 
 	hostdata = (struct NCR5380_hostdata *)instance->hostdata;
 
-	local_irq_save(flags);
+	spin_lock_irqsave(&hostdata->lock, flags);
 	if (!hostdata->connected)
 		seq_printf(m, "scsi%d: no currently connected command\n", HOSTNO);
 	else
@@ -758,7 +752,7 @@ static int __maybe_unused NCR5380_show_i
 	     ptr = NEXT(ptr))
 		show_Scsi_Cmnd(ptr, m);
 
-	local_irq_restore(flags);
+	spin_unlock_irqrestore(&hostdata->lock, flags);
 	return 0;
 }
 
@@ -795,6 +789,7 @@ static int __init NCR5380_init(struct Sc
 #if defined (REAL_DMA)
 	hostdata->dma_len = 0;
 #endif
+	spin_lock_init(&hostdata->lock);
 	hostdata->connected = NULL;
 	hostdata->issue_queue = NULL;
 	hostdata->disconnected_queue = NULL;
@@ -943,7 +938,7 @@ static int NCR5380_queue_command(struct
 	if (!NCR5380_acquire_dma_irq(instance))
 		return SCSI_MLQUEUE_HOST_BUSY;
 
-	local_irq_save(flags);
+	spin_lock_irqsave(&hostdata->lock, flags);
 
 	/*
 	 * Insert the cmd into the issue queue. Note that REQUEST SENSE
@@ -963,7 +958,7 @@ static int NCR5380_queue_command(struct
 		LIST(cmd, tmp);
 		SET_NEXT(tmp, cmd);
 	}
-	local_irq_restore(flags);
+	spin_unlock_irqrestore(&hostdata->lock, flags);
 
 	dprintk(NDEBUG_QUEUES, "scsi%d: command added to %s of queue\n", H_NO(cmd),
 		  (cmd->cmnd[0] == REQUEST_SENSE) ? "head" : "tail");
@@ -1003,7 +998,6 @@ static void NCR5380_main(struct work_str
 	struct Scsi_Host *instance = hostdata->host;
 	struct scsi_cmnd *tmp, *prev;
 	int done;
-	unsigned long flags;
 
 	/*
 	 * ++roman: Just disabling the NCR interrupt isn't sufficient here,
@@ -1011,9 +1005,8 @@ static void NCR5380_main(struct work_str
 	 * alter queues and touch the Falcon lock.
 	 */
 
-	local_save_flags(flags);
+	spin_lock_irq(&hostdata->lock);
 	do {
-		local_irq_disable();	/* Freeze request queues */
 		done = 1;
 
 		if (!hostdata->connected) {
@@ -1040,7 +1033,6 @@ static void NCR5380_main(struct work_str
 				        tmp, scmd_id(tmp), hostdata->busy[scmd_id(tmp)],
 				        lun);
 				/*  When we find one, remove it from the issue queue. */
-				/* ++guenther: possible race with Falcon locking */
 				if (
 #ifdef SUPPORT_TAGS
 				    !is_lun_busy( tmp, tmp->cmnd[0] != REQUEST_SENSE)
@@ -1048,8 +1040,6 @@ static void NCR5380_main(struct work_str
 				    !(hostdata->busy[tmp->device->id] & (1 << lun))
 #endif
 				    ) {
-					/* ++guenther: just to be sure, this must be atomic */
-					local_irq_disable();
 					if (prev) {
 						REMOVE(prev, NEXT(prev), tmp, NEXT(tmp));
 						SET_NEXT(prev, NEXT(tmp));
@@ -1060,9 +1050,6 @@ static void NCR5380_main(struct work_str
 					SET_NEXT(tmp, NULL);
 					hostdata->retain_dma_intr++;
 
-					/* reenable interrupts after finding one */
-					local_irq_restore(flags);
-
 					/*
 					 * Attempt to establish an I_T_L nexus here.
 					 * On success, instance->hostdata->connected is set.
@@ -1087,13 +1074,10 @@ static void NCR5380_main(struct work_str
 #endif
 					if (!NCR5380_select(instance, tmp)) {
 						/* OK or bad target */
-						local_irq_disable();
 						hostdata->retain_dma_intr--;
 						maybe_release_dma_irq(instance);
-						local_irq_restore(flags);
 					} else {
 						/* Need to retry */
-						local_irq_disable();
 						LIST(tmp, hostdata->issue_queue);
 						SET_NEXT(tmp, hostdata->issue_queue);
 						hostdata->issue_queue = tmp;
@@ -1101,7 +1085,6 @@ static void NCR5380_main(struct work_str
 						cmd_free_tag(tmp);
 #endif
 						hostdata->retain_dma_intr--;
-						local_irq_restore(flags);
 						done = 0;
 						dprintk(NDEBUG_MAIN, "scsi%d: main(): select() failed, "
 							    "returned to issue_queue\n", HOSTNO);
@@ -1117,7 +1100,6 @@ static void NCR5380_main(struct work_str
 		    && !hostdata->dma_len
 #endif
 		    ) {
-			local_irq_restore(flags);
 			dprintk(NDEBUG_MAIN, "scsi%d: main: performing information transfer\n",
 				    HOSTNO);
 			NCR5380_information_transfer(instance);
@@ -1125,7 +1107,7 @@ static void NCR5380_main(struct work_str
 			done = 0;
 		}
 	} while (!done);
-	local_irq_restore(flags);
+	spin_unlock_irq(&hostdata->lock);
 }
 
 
@@ -1254,6 +1236,9 @@ static irqreturn_t NCR5380_intr(int irq,
 	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) {
@@ -1313,6 +1298,8 @@ static irqreturn_t NCR5380_intr(int irq,
 #endif
 	}
 
+	spin_unlock_irqrestore(&hostdata->lock, flags);
+
 	return IRQ_RETVAL(handled);
 }
 
@@ -1352,7 +1339,6 @@ static int NCR5380_select(struct Scsi_Ho
 	unsigned char *data;
 	int len;
 	int err;
-	unsigned long flags;
 
 	NCR5380_dprint(NDEBUG_ARBITRATION, instance);
 	dprintk(NDEBUG_ARBITRATION, "scsi%d: starting arbitration, id = %d\n", HOSTNO,
@@ -1363,11 +1349,6 @@ static int NCR5380_select(struct Scsi_Ho
 	 * data bus during SELECTION.
 	 */
 
-	local_irq_save(flags);
-	if (hostdata->connected) {
-		local_irq_restore(flags);
-		return -1;
-	}
 	NCR5380_write(TARGET_COMMAND_REG, 0);
 
 	/*
@@ -1381,10 +1362,11 @@ static int NCR5380_select(struct Scsi_Ho
 	 * Bus Free Delay, arbitration will begin.
 	 */
 
-	local_irq_restore(flags);
+	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 */
 		return -1;
@@ -1395,6 +1377,7 @@ static int NCR5380_select(struct Scsi_Ho
 		             "select: arbitration timeout\n");
 		return -1;
 	}
+	spin_unlock_irq(&hostdata->lock);
 
 	/* The SCSI-2 arbitration delay is 2.4 us */
 	udelay(3);
@@ -1402,11 +1385,11 @@ static int NCR5380_select(struct Scsi_Ho
 	/* 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) ||
-	    hostdata->connected) {
+	    (NCR5380_read(INITIATOR_COMMAND_REG) & ICR_ARBITRATION_LOST)) {
 		NCR5380_write(MODE_REG, MR_BASE);
 		dprintk(NDEBUG_ARBITRATION, "scsi%d: lost arbitration, deasserting MR_ARBITRATE\n",
 			   HOSTNO);
+		spin_lock_irq(&hostdata->lock);
 		return -1;
 	}
 
@@ -1421,12 +1404,12 @@ static int NCR5380_select(struct Scsi_Ho
 	 * Seems to work with only Mustek scanner attached.
 	 */
 	if (!(hostdata->flags & FLAG_DTC3181E) &&
-	    ((NCR5380_read(INITIATOR_COMMAND_REG) & ICR_ARBITRATION_LOST) ||
-	     hostdata->connected)) {
+	    (NCR5380_read(INITIATOR_COMMAND_REG) & ICR_ARBITRATION_LOST)) {
 		NCR5380_write(MODE_REG, MR_BASE);
 		NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
 		dprintk(NDEBUG_ARBITRATION, "scsi%d: lost arbitration, deasserting ICR_ASSERT_SEL\n",
 			   HOSTNO);
+		spin_lock_irq(&hostdata->lock);
 		return -1;
 	}
 
@@ -1440,6 +1423,8 @@ static int NCR5380_select(struct Scsi_Ho
 	else
 		udelay(2);
 
+	spin_lock_irq(&hostdata->lock);
+
 	/* NCR5380_reselect() clears MODE_REG after a reselection interrupt */
 	if (!(NCR5380_read(MODE_REG) & MR_ARBITRATE))
 		return -1;
@@ -1467,14 +1452,10 @@ static int NCR5380_select(struct Scsi_Ho
 	 * Reselect interrupts must be turned off prior to the dropping of BSY,
 	 * otherwise we will trigger an interrupt.
 	 */
-
-	if (hostdata->connected) {
-		NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
-		return -1;
-	}
-
 	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.
@@ -1515,6 +1496,7 @@ static int NCR5380_select(struct Scsi_Ho
 	                            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)
@@ -1525,6 +1507,7 @@ static int NCR5380_select(struct Scsi_Ho
 	}
 
 	if (err < 0) {
+		spin_lock_irq(&hostdata->lock);
 		NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
 		cmd->result = DID_BAD_TARGET << 16;
 #ifdef SUPPORT_TAGS
@@ -1564,6 +1547,7 @@ static int NCR5380_select(struct Scsi_Ho
 	/* 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);
@@ -1593,6 +1577,7 @@ static int NCR5380_select(struct Scsi_Ho
 	NCR5380_transfer_pio(instance, &phase, &len, &data);
 	dprintk(NDEBUG_SELECTION, "scsi%d: nexus established.\n", HOSTNO);
 	/* XXX need to handle errors here */
+
 	hostdata->connected = cmd;
 #ifndef SUPPORT_TAGS
 	hostdata->busy[cmd->device->id] |= (1 << cmd->device->lun);
@@ -1859,7 +1844,6 @@ static int NCR5380_transfer_dma(struct S
 	SETUP_HOSTDATA(instance);
 	register int c = *count;
 	register unsigned char p = *phase;
-	unsigned long flags;
 
 #if defined(CONFIG_SUN3)
 	/* sanity check */
@@ -1875,7 +1859,6 @@ static int NCR5380_transfer_dma(struct S
 		c, (p & SR_IO) ? "to" : "from", *data);
 
 	/* netbsd turns off ints here, why not be safe and do it too */
-	local_irq_save(flags);
 
 	/* send start chain */
 	sun3scsi_dma_start(c, *data);
@@ -1895,8 +1878,6 @@ static int NCR5380_transfer_dma(struct S
 	dregs->csr |= CSR_DMA_ENABLE;
 #endif
 
-	local_irq_restore(flags);
-
 	sun3_dma_active = 1;
 
 #else /* !defined(CONFIG_SUN3) */
@@ -1923,11 +1904,9 @@ static int NCR5380_transfer_dma(struct S
 		/* On the Medusa, it is a must to initialize the DMA before
 		 * starting the NCR. This is also the cleaner way for the TT.
 		 */
-		local_irq_save(flags);
 		hostdata->dma_len = (p & SR_IO) ?
 			NCR5380_dma_read_setup(instance, d, c) :
 			NCR5380_dma_write_setup(instance, d, c);
-		local_irq_restore(flags);
 	}
 
 	if (p & SR_IO)
@@ -1941,11 +1920,9 @@ static int NCR5380_transfer_dma(struct S
 		/* On the Falcon, the DMA setup must be done after the last */
 		/* NCR access, else the DMA setup gets trashed!
 		 */
-		local_irq_save(flags);
 		hostdata->dma_len = (p & SR_IO) ?
 			NCR5380_dma_read_setup(instance, d, c) :
 			NCR5380_dma_write_setup(instance, d, c);
-		local_irq_restore(flags);
 	}
 #endif /* !defined(CONFIG_SUN3) */
 
@@ -1973,7 +1950,6 @@ static int NCR5380_transfer_dma(struct S
 static void NCR5380_information_transfer(struct Scsi_Host *instance)
 {
 	SETUP_HOSTDATA(instance);
-	unsigned long flags;
 	unsigned char msgout = NOP;
 	int sink = 0;
 	int len;
@@ -1982,13 +1958,13 @@ static void NCR5380_information_transfer
 #endif
 	unsigned char *data;
 	unsigned char phase, tmp, extended_msg[10], old_phase = 0xff;
-	struct scsi_cmnd *cmd = (struct scsi_cmnd *) hostdata->connected;
+	struct scsi_cmnd *cmd;
 
 #ifdef SUN3_SCSI_VME
 	dregs->csr |= CSR_INTR;
 #endif
 
-	while (1) {
+	while ((cmd = hostdata->connected)) {
 		tmp = NCR5380_read(STATUS_REG);
 		/* We only have a valid SCSI phase when REQ is asserted */
 		if (tmp & SR_REQ) {
@@ -2122,9 +2098,13 @@ static void NCR5380_information_transfer
 					}
 				} else
 #endif /* defined(REAL_DMA) */
+				{
+					spin_unlock_irq(&hostdata->lock);
 					NCR5380_transfer_pio(instance, &phase,
 							     (int *)&cmd->SCp.this_residual,
 							     (unsigned char **)&cmd->SCp.ptr);
+					spin_lock_irq(&hostdata->lock);
+				}
 #if defined(CONFIG_SUN3) && defined(REAL_DMA)
 				/* if we had intended to dma that command clear it */
 				if (sun3_dma_setup_done == cmd)
@@ -2134,7 +2114,6 @@ static void NCR5380_information_transfer
 			case PHASE_MSGIN:
 				len = 1;
 				data = &tmp;
-				NCR5380_write(SELECT_ENABLE_REG, 0);	/* disable reselects */
 				NCR5380_transfer_pio(instance, &phase, &len, &data);
 				cmd->SCp.Message = tmp;
 
@@ -2146,7 +2125,6 @@ static void NCR5380_information_transfer
 					dprintk(NDEBUG_QUEUES, "scsi%d: command for target %d, lun %llu "
 						  "completed\n", HOSTNO, cmd->device->id, cmd->device->lun);
 
-					local_irq_save(flags);
 					hostdata->connected = NULL;
 #ifdef SUPPORT_TAGS
 					cmd_free_tag(cmd);
@@ -2162,8 +2140,6 @@ static void NCR5380_information_transfer
 #else
 					hostdata->busy[cmd->device->id] &= ~(1 << cmd->device->lun);
 #endif
-					/* Enable reselect interrupts */
-					NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
 
 					/*
 					 * I'm not sure what the correct thing to do here is :
@@ -2221,13 +2197,10 @@ static void NCR5380_information_transfer
 					 * disconnected queue.
 					 */
 					maybe_release_dma_irq(instance);
-					local_irq_restore(flags);
 					return;
 				case MESSAGE_REJECT:
 					/* Accept message by clearing ACK */
 					NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
-					/* Enable reselect interrupts */
-					NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
 					switch (hostdata->last_message) {
 					case HEAD_OF_QUEUE_TAG:
 					case ORDERED_QUEUE_TAG:
@@ -2251,12 +2224,10 @@ static void NCR5380_information_transfer
 				case DISCONNECT:
 					/* Accept message by clearing ACK */
 					NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
-					local_irq_save(flags);
 					LIST(cmd,hostdata->disconnected_queue);
 					SET_NEXT(cmd, hostdata->disconnected_queue);
 					hostdata->connected = NULL;
 					hostdata->disconnected_queue = cmd;
-					local_irq_restore(flags);
 					dprintk(NDEBUG_QUEUES, "scsi%d: command for target %d lun %llu was "
 						  "moved from connected to the "
 						  "disconnected_queue\n", HOSTNO,
@@ -2287,8 +2258,6 @@ static void NCR5380_information_transfer
 				case RESTORE_POINTERS:
 					/* Accept message by clearing ACK */
 					NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
-					/* Enable reselect interrupts */
-					NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
 					break;
 				case EXTENDED_MESSAGE:
 					/*
@@ -2307,6 +2276,8 @@ static void NCR5380_information_transfer
 					/* Accept first byte by clearing ACK */
 					NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
 
+					spin_unlock_irq(&hostdata->lock);
+
 					dprintk(NDEBUG_EXTENDED, "scsi%d: receiving extended message\n", HOSTNO);
 
 					len = 2;
@@ -2345,6 +2316,11 @@ static void NCR5380_information_transfer
 							   HOSTNO, extended_msg[2], extended_msg[1]);
 						tmp = 0;
 					}
+
+					spin_lock_irq(&hostdata->lock);
+					if (!hostdata->connected)
+						return;
+
 					/* Fall through to reject message */
 
 					/*
@@ -2377,7 +2353,6 @@ static void NCR5380_information_transfer
 				hostdata->last_message = msgout;
 				NCR5380_transfer_pio(instance, &phase, &len, &data);
 				if (msgout == ABORT) {
-					local_irq_save(flags);
 #ifdef SUPPORT_TAGS
 					cmd_free_tag(cmd);
 #else
@@ -2386,7 +2361,6 @@ static void NCR5380_information_transfer
 					hostdata->connected = NULL;
 					cmd->result = DID_ERROR << 16;
 					maybe_release_dma_irq(instance);
-					local_irq_restore(flags);
 					cmd->scsi_done(cmd);
 					NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
 					return;
@@ -2414,9 +2388,11 @@ static void NCR5380_information_transfer
 				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);
 		}
-	} /* while (1) */
+	}
 }
 
 /*
@@ -2649,9 +2625,9 @@ int NCR5380_abort(struct scsi_cmnd *cmd)
 
 	scmd_printk(KERN_NOTICE, cmd, "aborting command\n");
 
-	NCR5380_print_status(instance);
+	spin_lock_irqsave(&hostdata->lock, flags);
 
-	local_irq_save(flags);
+	NCR5380_print_status(instance);
 
 	dprintk(NDEBUG_ABORT, "scsi%d: abort called basr 0x%02x, sr 0x%02x\n", HOSTNO,
 		    NCR5380_read(BUS_AND_STATUS_REG),
@@ -2693,11 +2669,11 @@ int NCR5380_abort(struct scsi_cmnd *cmd)
 			hostdata->busy[cmd->device->id] &= ~(1 << cmd->device->lun);
 #endif
 			maybe_release_dma_irq(instance);
-			local_irq_restore(flags);
+			spin_unlock_irqrestore(&hostdata->lock, flags);
 			cmd->scsi_done(cmd);
 			return SUCCESS;
 		} else {
-			local_irq_restore(flags);
+			spin_unlock_irqrestore(&hostdata->lock, flags);
 			printk("scsi%d: abort of connected command failed!\n", HOSTNO);
 			return FAILED;
 		}
@@ -2717,7 +2693,7 @@ int NCR5380_abort(struct scsi_cmnd *cmd)
 			SET_NEXT(tmp, NULL);
 			tmp->result = DID_ABORT << 16;
 			maybe_release_dma_irq(instance);
-			local_irq_restore(flags);
+			spin_unlock_irqrestore(&hostdata->lock, flags);
 			dprintk(NDEBUG_ABORT, "scsi%d: abort removed command from issue queue.\n",
 				    HOSTNO);
 			/* Tagged queuing note: no tag to free here, hasn't been assigned
@@ -2739,7 +2715,7 @@ int NCR5380_abort(struct scsi_cmnd *cmd)
 	 */
 
 	if (hostdata->connected) {
-		local_irq_restore(flags);
+		spin_unlock_irqrestore(&hostdata->lock, flags);
 		dprintk(NDEBUG_ABORT, "scsi%d: abort failed, command connected.\n", HOSTNO);
 		return FAILED;
 	}
@@ -2772,17 +2748,16 @@ int NCR5380_abort(struct scsi_cmnd *cmd)
 	for (tmp = (struct scsi_cmnd *) hostdata->disconnected_queue; tmp;
 	     tmp = NEXT(tmp)) {
 		if (cmd == tmp) {
-			local_irq_restore(flags);
 			dprintk(NDEBUG_ABORT, "scsi%d: aborting disconnected command.\n", HOSTNO);
 
-			if (NCR5380_select(instance, cmd))
+			if (NCR5380_select(instance, cmd)) {
+				spin_unlock_irq(&hostdata->lock);
 				return FAILED;
-
+			}
 			dprintk(NDEBUG_ABORT, "scsi%d: nexus reestablished.\n", HOSTNO);
 
 			do_abort(instance);
 
-			local_irq_save(flags);
 			for (prev = (struct scsi_cmnd **)&(hostdata->disconnected_queue),
 			     tmp = (struct scsi_cmnd *)hostdata->disconnected_queue;
 			     tmp; prev = NEXTADDR(tmp), tmp = NEXT(tmp)) {
@@ -2801,7 +2776,7 @@ int NCR5380_abort(struct scsi_cmnd *cmd)
 					hostdata->busy[cmd->device->id] &= ~(1 << cmd->device->lun);
 #endif
 					maybe_release_dma_irq(instance);
-					local_irq_restore(flags);
+					spin_unlock_irqrestore(&hostdata->lock, flags);
 					tmp->scsi_done(tmp);
 					return SUCCESS;
 				}
@@ -2814,7 +2789,7 @@ int NCR5380_abort(struct scsi_cmnd *cmd)
 	 * released after the abort, in case it is kept due to some bug.
 	 */
 	maybe_release_dma_irq(instance);
-	local_irq_restore(flags);
+	spin_unlock_irqrestore(&hostdata->lock, flags);
 
 	/*
 	 * Case 5 : If we reached this point, the command was not found in any of
@@ -2846,7 +2821,7 @@ static int NCR5380_bus_reset(struct scsi
 	int i;
 	unsigned long flags;
 
-	local_irq_save(flags);
+	spin_lock_irqsave(&hostdata->lock, flags);
 
 #if (NDEBUG & NDEBUG_ANY)
 	scmd_printk(KERN_INFO, cmd, "performing bus reset\n");
@@ -2886,7 +2861,7 @@ static int NCR5380_bus_reset(struct scsi
 #endif
 
 	maybe_release_dma_irq(instance);
-	local_irq_restore(flags);
+	spin_unlock_irqrestore(&hostdata->lock, flags);
 
 	return SUCCESS;
 }
Index: linux/drivers/scsi/NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/NCR5380.c	2015-11-18 19:34:08.000000000 +1100
+++ linux/drivers/scsi/NCR5380.c	2015-11-18 19:34:10.000000000 +1100
@@ -624,6 +624,7 @@ static int __maybe_unused NCR5380_show_i
 {
 	struct NCR5380_hostdata *hostdata;
 	struct scsi_cmnd *ptr;
+	unsigned long flags;
 
 	hostdata = (struct NCR5380_hostdata *) instance->hostdata;
 
@@ -631,7 +632,7 @@ static int __maybe_unused NCR5380_show_i
 	seq_printf(m, "Highwater I/O busy spin counts: write %d, read %d\n",
 	        hostdata->spin_max_w, hostdata->spin_max_r);
 #endif
-	spin_lock_irq(instance->host_lock);
+	spin_lock_irqsave(&hostdata->lock, flags);
 	if (!hostdata->connected)
 		seq_printf(m, "scsi%d: no currently connected command\n", instance->host_no);
 	else
@@ -643,7 +644,7 @@ static int __maybe_unused NCR5380_show_i
 	seq_printf(m, "scsi%d: disconnected_queue\n", instance->host_no);
 	for (ptr = (struct scsi_cmnd *) hostdata->disconnected_queue; ptr; ptr = (struct scsi_cmnd *) ptr->host_scribble)
 		lprint_Scsi_Cmnd(ptr, m);
-	spin_unlock_irq(instance->host_lock);
+	spin_unlock_irqrestore(&hostdata->lock, flags);
 	return 0;
 }
 
@@ -702,6 +703,7 @@ static int NCR5380_init(struct Scsi_Host
 #ifdef REAL_DMA
 	hostdata->dmalen = 0;
 #endif
+	spin_lock_init(&hostdata->lock);
 	hostdata->connected = NULL;
 	hostdata->issue_queue = NULL;
 	hostdata->disconnected_queue = NULL;
@@ -826,7 +828,7 @@ static int NCR5380_queue_command(struct
 	cmd->host_scribble = NULL;
 	cmd->result = 0;
 
-	spin_lock_irqsave(instance->host_lock, flags);
+	spin_lock_irqsave(&hostdata->lock, flags);
 
 	/* 
 	 * Insert the cmd into the issue queue. Note that REQUEST SENSE 
@@ -844,7 +846,7 @@ static int NCR5380_queue_command(struct
 		LIST(cmd, tmp);
 		tmp->host_scribble = (unsigned char *) cmd;
 	}
-	spin_unlock_irqrestore(instance->host_lock, flags);
+	spin_unlock_irqrestore(&hostdata->lock, flags);
 
 	dprintk(NDEBUG_QUEUES, "scsi%d : command added to %s of queue\n", instance->host_no, (cmd->cmnd[0] == REQUEST_SENSE) ? "head" : "tail");
 
@@ -873,10 +875,10 @@ static void NCR5380_main(struct work_str
 	struct scsi_cmnd *tmp, *prev;
 	int done;
 	
-	spin_lock_irq(instance->host_lock);
+	spin_lock_irq(&hostdata->lock);
 	do {
-		/* Lock held here */
 		done = 1;
+
 		if (!hostdata->connected) {
 			dprintk(NDEBUG_MAIN, "scsi%d : not connected\n", instance->host_no);
 			/*
@@ -926,11 +928,10 @@ static void NCR5380_main(struct work_str
 					}
 					if (hostdata->connected)
 						break;
-					/* lock held here still */
 				}	/* if target/lun is not busy */
 			}	/* for */
-			/* exited locked */
 		}	/* if (!hostdata->connected) */
+
 		if (hostdata->connected
 #ifdef REAL_DMA
 		    && !hostdata->dmalen
@@ -942,8 +943,7 @@ static void NCR5380_main(struct work_str
 			done = 0;
 		}
 	} while (!done);
-	
-	spin_unlock_irq(instance->host_lock);
+	spin_unlock_irq(&hostdata->lock);
 }
 
 #ifndef DONT_USE_INTR
@@ -990,7 +990,7 @@ static irqreturn_t NCR5380_intr(int irq,
 	unsigned char basr;
 	unsigned long flags;
 
-	spin_lock_irqsave(instance->host_lock, flags);
+	spin_lock_irqsave(&hostdata->lock, flags);
 
 	basr = NCR5380_read(BUS_AND_STATUS_REG);
 	if (basr & BASR_IRQ) {
@@ -1054,7 +1054,7 @@ static irqreturn_t NCR5380_intr(int irq,
 		shost_printk(KERN_NOTICE, instance, "interrupt without IRQ bit\n");
 	}
 
-	spin_unlock_irqrestore(instance->host_lock, flags);
+	spin_unlock_irqrestore(&hostdata->lock, flags);
 
 	return IRQ_RETVAL(handled);
 }
@@ -1121,11 +1121,11 @@ static int NCR5380_select(struct Scsi_Ho
 	 * Bus Free Delay, arbitration will begin.
 	 */
 
-	spin_unlock_irq(instance->host_lock);
+	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(instance->host_lock);
+	spin_lock_irq(&hostdata->lock);
 	if (!(NCR5380_read(MODE_REG) & MR_ARBITRATE)) {
 		/* Reselection interrupt */
 		return -1;
@@ -1136,6 +1136,7 @@ static int NCR5380_select(struct Scsi_Ho
 		             "select: arbitration timeout\n");
 		return -1;
 	}
+	spin_unlock_irq(&hostdata->lock);
 
 	/* The SCSI-2 arbitration delay is 2.4 us */
 	udelay(3);
@@ -1144,6 +1145,7 @@ static int NCR5380_select(struct Scsi_Ho
 	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);
 		dprintk(NDEBUG_ARBITRATION, "scsi%d : lost arbitration, deasserting MR_ARBITRATE\n", instance->host_no);
+		spin_lock_irq(&hostdata->lock);
 		return -1;
 	}
 
@@ -1162,6 +1164,7 @@ static int NCR5380_select(struct Scsi_Ho
 		NCR5380_write(MODE_REG, MR_BASE);
 		NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
 		dprintk(NDEBUG_ARBITRATION, "scsi%d : lost arbitration, deasserting ICR_ASSERT_SEL\n", instance->host_no);
+		spin_lock_irq(&hostdata->lock);
 		return -1;
 	}
 	/* 
@@ -1174,6 +1177,8 @@ static int NCR5380_select(struct Scsi_Ho
 	else
 		udelay(2);
 
+	spin_lock_irq(&hostdata->lock);
+
 	/* NCR5380_reselect() clears MODE_REG after a reselection interrupt */
 	if (!(NCR5380_read(MODE_REG) & MR_ARBITRATE))
 		return -1;
@@ -1202,6 +1207,8 @@ static int NCR5380_select(struct Scsi_Ho
 	 */
 	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.
@@ -1241,6 +1248,7 @@ static int NCR5380_select(struct Scsi_Ho
 	                            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)
@@ -1250,6 +1258,7 @@ static int NCR5380_select(struct Scsi_Ho
 	}
 
 	if (err < 0) {
+		spin_lock_irq(&hostdata->lock);
 		NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
 		cmd->result = DID_BAD_TARGET << 16;
 		cmd->scsi_done(cmd);
@@ -1286,9 +1295,8 @@ static int NCR5380_select(struct Scsi_Ho
 
 	/* Wait for start of REQ/ACK handshake */
 
-	spin_unlock_irq(instance->host_lock);
 	err = NCR5380_poll_politely(instance, STATUS_REG, SR_REQ, SR_REQ, HZ);
-	spin_lock_irq(instance->host_lock);
+	spin_lock_irq(&hostdata->lock);
 	if (err < 0) {
 		shost_printk(KERN_ERR, instance, "select: REQ timeout\n");
 		NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
@@ -1308,6 +1316,7 @@ static int NCR5380_select(struct Scsi_Ho
 	NCR5380_transfer_pio(instance, &phase, &len, &data);
 	dprintk(NDEBUG_SELECTION, "scsi%d : nexus established.\n", instance->host_no);
 	/* XXX need to handle errors here */
+
 	hostdata->connected = cmd;
 	hostdata->busy[cmd->device->id] |= (1 << (cmd->device->lun & 0xFF));
 
@@ -1811,9 +1820,9 @@ static void NCR5380_information_transfer
 #endif
 	unsigned char *data;
 	unsigned char phase, tmp, extended_msg[10], old_phase = 0xff;
-	struct scsi_cmnd *cmd = (struct scsi_cmnd *) hostdata->connected;
+	struct scsi_cmnd *cmd;
 
-	while (1) {
+	while ((cmd = hostdata->connected)) {
 		tmp = NCR5380_read(STATUS_REG);
 		/* We only have a valid SCSI phase when REQ is asserted */
 		if (tmp & SR_REQ) {
@@ -1889,8 +1898,12 @@ static void NCR5380_information_transfer
 						cmd->SCp.this_residual -= transfersize - len;
 				} else
 #endif				/* defined(PSEUDO_DMA) || defined(REAL_DMA_POLL) */
+				{
+					spin_unlock_irq(&hostdata->lock);
 					NCR5380_transfer_pio(instance, &phase, (int *) &cmd->SCp.this_residual, (unsigned char **)
 							     &cmd->SCp.ptr);
+					spin_lock_irq(&hostdata->lock);
+				}
 				break;
 			case PHASE_MSGIN:
 				len = 1;
@@ -2022,6 +2035,9 @@ static void NCR5380_information_transfer
 					extended_msg[0] = EXTENDED_MESSAGE;
 					/* Accept first byte by clearing ACK */
 					NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
+
+					spin_unlock_irq(&hostdata->lock);
+
 					dprintk(NDEBUG_EXTENDED, "scsi%d : receiving extended message\n", instance->host_no);
 
 					len = 2;
@@ -2056,6 +2072,11 @@ static void NCR5380_information_transfer
 						printk("scsi%d: extended message code %02x length %d is too long\n", instance->host_no, extended_msg[2], extended_msg[1]);
 						tmp = 0;
 					}
+
+					spin_lock_irq(&hostdata->lock);
+					if (!hostdata->connected)
+						return;
+
 					/* Fall through to reject message */
 
 					/* 
@@ -2115,11 +2136,11 @@ static void NCR5380_information_transfer
 				NCR5380_dprint(NDEBUG_ANY, instance);
 			}	/* switch(phase) */
 		} else {
-			spin_unlock_irq(instance->host_lock);
+			spin_unlock_irq(&hostdata->lock);
 			NCR5380_poll_politely(instance, STATUS_REG, SR_REQ, SR_REQ, HZ);
-			spin_lock_irq(instance->host_lock);
+			spin_lock_irq(&hostdata->lock);
 		}
-	}			/* while (1) */
+	}
 }
 
 /*
@@ -2315,10 +2336,12 @@ static int NCR5380_abort(struct scsi_cmn
 	struct Scsi_Host *instance = cmd->device->host;
 	struct NCR5380_hostdata *hostdata = (struct NCR5380_hostdata *) instance->hostdata;
 	struct scsi_cmnd *tmp, **prev;
+	unsigned long flags;
 
 	scmd_printk(KERN_WARNING, cmd, "aborting command\n");
 
-	spin_lock_irq(instance->host_lock);
+	spin_lock_irqsave(&hostdata->lock, flags);
+
 	NCR5380_print_status(instance);
 
 	dprintk(NDEBUG_ABORT, "scsi%d : abort called\n", instance->host_no);
@@ -2365,7 +2388,7 @@ static int NCR5380_abort(struct scsi_cmn
 			REMOVE(5, *prev, tmp, tmp->host_scribble);
 			(*prev) = (struct scsi_cmnd *) tmp->host_scribble;
 			tmp->host_scribble = NULL;
-			spin_unlock_irq(instance->host_lock);
+			spin_unlock_irqrestore(&hostdata->lock, flags);
 			tmp->result = DID_ABORT << 16;
 			dprintk(NDEBUG_ABORT, "scsi%d : abort removed command from issue queue.\n", instance->host_no);
 			tmp->scsi_done(tmp);
@@ -2389,7 +2412,7 @@ static int NCR5380_abort(struct scsi_cmn
  */
 
 	if (hostdata->connected) {
-		spin_unlock_irq(instance->host_lock);
+		spin_unlock_irqrestore(&hostdata->lock, flags);
 		dprintk(NDEBUG_ABORT, "scsi%d : abort failed, command connected.\n", instance->host_no);
 		return FAILED;
 	}
@@ -2423,7 +2446,7 @@ static int NCR5380_abort(struct scsi_cmn
 			dprintk(NDEBUG_ABORT, "scsi%d : aborting disconnected command.\n", instance->host_no);
 
 			if (NCR5380_select(instance, cmd)) {
-				spin_unlock_irq(instance->host_lock);
+				spin_unlock_irq(&hostdata->lock);
 				return FAILED;
 			}
 			dprintk(NDEBUG_ABORT, "scsi%d : nexus reestablished.\n", instance->host_no);
@@ -2435,7 +2458,7 @@ static int NCR5380_abort(struct scsi_cmn
 					REMOVE(5, *prev, tmp, tmp->host_scribble);
 					*prev = (struct scsi_cmnd *) tmp->host_scribble;
 					tmp->host_scribble = NULL;
-					spin_unlock_irq(instance->host_lock);
+					spin_unlock_irqrestore(&hostdata->lock, flags);
 					tmp->result = DID_ABORT << 16;
 					tmp->scsi_done(tmp);
 					return SUCCESS;
@@ -2450,7 +2473,7 @@ static int NCR5380_abort(struct scsi_cmn
  * so we won't panic, but we will notify the user in case something really
  * broke.
  */
-	spin_unlock_irq(instance->host_lock);
+	spin_unlock_irqrestore(&hostdata->lock, flags);
 	printk(KERN_WARNING "scsi%d : warning : SCSI command probably completed successfully\n"
 			"         before abortion\n", instance->host_no);
 	return FAILED;
@@ -2467,8 +2490,10 @@ static int NCR5380_abort(struct scsi_cmn
 static int NCR5380_bus_reset(struct scsi_cmnd *cmd)
 {
 	struct Scsi_Host *instance = cmd->device->host;
+	struct NCR5380_hostdata *hostdata = shost_priv(instance);
+	unsigned long flags;
 
-	spin_lock_irq(instance->host_lock);
+	spin_lock_irqsave(&hostdata->lock, flags);
 
 #if (NDEBUG & NDEBUG_ANY)
 	scmd_printk(KERN_INFO, cmd, "performing bus reset\n");
@@ -2477,7 +2502,7 @@ static int NCR5380_bus_reset(struct scsi
 
 	do_reset(instance);
 
-	spin_unlock_irq(instance->host_lock);
+	spin_unlock_irqrestore(&hostdata->lock, flags);
 
 	return SUCCESS;
 }

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

* [PATCH 51/71] ncr5380: Remove command list debug code
  2015-11-18  8:34 ` Finn Thain
  (?)
@ 2015-11-18  8:35   ` Finn Thain
  -1 siblings, 0 replies; 268+ messages in thread
From: Finn Thain @ 2015-11-18  8:35 UTC (permalink / raw)
  To: James E.J. Bottomley, Michael Schmitz, linux-m68k, linux-scsi,
	linux-kernel, Russell King, linux-arm-kernel

[-- Attachment #1: ncr5380-remove-cmd-list-debug-code --]
[-- Type: text/plain, Size: 11702 bytes --]

Some NCR5380 hosts offer a .show_info method to access the contents of
the various command list data structures from a procfs file. When NDEBUG
is set, the same information is sent to the console during EH.

The two core drivers, atari_NCR5380.c and NCR5380.c differ here. Because
it is just for debugging, the easiest way to fix the discrepancy is
simply remove this code.

The only remaining users of NCR5380_show_info() and NCR5380_write_info()
are drivers that define PSEUDO_DMA. The others have no use for the
.show_info method, so don't initialize it.

Signed-off-by: Finn Thain <fthain@telegraphics.com.au>

---
 drivers/scsi/NCR5380.c       |   70 ++------------------------------
 drivers/scsi/arm/oak.c       |    2 
 drivers/scsi/atari_NCR5380.c |   94 +------------------------------------------
 drivers/scsi/atari_scsi.c    |    2 
 drivers/scsi/g_NCR5380.c     |    1 
 drivers/scsi/sun3_scsi.c     |    2 
 6 files changed, 9 insertions(+), 162 deletions(-)

Index: linux/drivers/scsi/NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/NCR5380.c	2015-11-18 19:34:10.000000000 +1100
+++ linux/drivers/scsi/NCR5380.c	2015-11-18 19:34:12.000000000 +1100
@@ -570,22 +570,6 @@ static void prepare_info(struct Scsi_Hos
 	         "");
 }
 
-/**
- *	NCR5380_print_status 	-	dump controller info
- *	@instance: controller to dump
- *
- *	Print commands in the various queues, called from NCR5380_abort 
- *	and NCR5380_debug to aid debugging.
- *
- *	Locks: called functions disable irqs
- */
-
-static void __maybe_unused NCR5380_print_status(struct Scsi_Host *instance)
-{
-	NCR5380_dprint(NDEBUG_ANY, instance);
-	NCR5380_dprint_phase(NDEBUG_ANY, instance);
-}
-
 #ifdef PSEUDO_DMA
 /******************************************/
 /*
@@ -610,65 +594,19 @@ static int __maybe_unused NCR5380_write_
 	hostdata->spin_max_w = 0;
 	return 0;
 }
-#endif
-
-static
-void lprint_Scsi_Cmnd(struct scsi_cmnd *cmd, struct seq_file *m);
-static
-void lprint_command(unsigned char *cmd, struct seq_file *m);
-static
-void lprint_opcode(int opcode, struct seq_file *m);
 
 static int __maybe_unused NCR5380_show_info(struct seq_file *m,
 	struct Scsi_Host *instance)
 {
 	struct NCR5380_hostdata *hostdata;
-	struct scsi_cmnd *ptr;
-	unsigned long flags;
 
 	hostdata = (struct NCR5380_hostdata *) instance->hostdata;
 
-#ifdef PSEUDO_DMA
 	seq_printf(m, "Highwater I/O busy spin counts: write %d, read %d\n",
 	        hostdata->spin_max_w, hostdata->spin_max_r);
-#endif
-	spin_lock_irqsave(&hostdata->lock, flags);
-	if (!hostdata->connected)
-		seq_printf(m, "scsi%d: no currently connected command\n", instance->host_no);
-	else
-		lprint_Scsi_Cmnd((struct scsi_cmnd *) hostdata->connected, m);
-	seq_printf(m, "scsi%d: issue_queue\n", instance->host_no);
-	for (ptr = (struct scsi_cmnd *) hostdata->issue_queue; ptr; ptr = (struct scsi_cmnd *) ptr->host_scribble)
-		lprint_Scsi_Cmnd(ptr, m);
-
-	seq_printf(m, "scsi%d: disconnected_queue\n", instance->host_no);
-	for (ptr = (struct scsi_cmnd *) hostdata->disconnected_queue; ptr; ptr = (struct scsi_cmnd *) ptr->host_scribble)
-		lprint_Scsi_Cmnd(ptr, m);
-	spin_unlock_irqrestore(&hostdata->lock, flags);
 	return 0;
 }
-
-static void lprint_Scsi_Cmnd(struct scsi_cmnd *cmd, struct seq_file *m)
-{
-	seq_printf(m, "scsi%d : destination target %d, lun %llu\n", cmd->device->host->host_no, cmd->device->id, cmd->device->lun);
-	seq_puts(m, "        command = ");
-	lprint_command(cmd->cmnd, m);
-}
-
-static void lprint_command(unsigned char *command, struct seq_file *m)
-{
-	int i, s;
-	lprint_opcode(command[0], m);
-	for (i = 1, s = COMMAND_SIZE(command[0]); i < s; ++i)
-		seq_printf(m, "%02x ", command[i]);
-	seq_putc(m, '\n');
-}
-
-static void lprint_opcode(int opcode, struct seq_file *m)
-{
-	seq_printf(m, "%2d (0x%02x)", opcode, opcode);
-}
-
+#endif
 
 /**
  *	NCR5380_init	-	initialise an NCR5380
@@ -2342,7 +2280,8 @@ static int NCR5380_abort(struct scsi_cmn
 
 	spin_lock_irqsave(&hostdata->lock, flags);
 
-	NCR5380_print_status(instance);
+	NCR5380_dprint(NDEBUG_ANY, instance);
+	NCR5380_dprint_phase(NDEBUG_ANY, instance);
 
 	dprintk(NDEBUG_ABORT, "scsi%d : abort called\n", instance->host_no);
 	dprintk(NDEBUG_ABORT, "        basr 0x%X, sr 0x%X\n", NCR5380_read(BUS_AND_STATUS_REG), NCR5380_read(STATUS_REG));
@@ -2497,8 +2436,9 @@ static int NCR5380_bus_reset(struct scsi
 
 #if (NDEBUG & NDEBUG_ANY)
 	scmd_printk(KERN_INFO, cmd, "performing bus reset\n");
-	NCR5380_print_status(instance);
 #endif
+	NCR5380_dprint(NDEBUG_ANY, instance);
+	NCR5380_dprint_phase(NDEBUG_ANY, instance);
 
 	do_reset(instance);
 
Index: linux/drivers/scsi/atari_NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/atari_NCR5380.c	2015-11-18 19:34:10.000000000 +1100
+++ linux/drivers/scsi/atari_NCR5380.c	2015-11-18 19:34:12.000000000 +1100
@@ -669,94 +669,6 @@ static void prepare_info(struct Scsi_Hos
 }
 
 /**
- * NCR5380_print_status - dump controller info
- * @instance: controller to dump
- *
- * Print commands in the various queues, called from NCR5380_abort
- * to aid debugging.
- */
-
-static void lprint_Scsi_Cmnd(struct scsi_cmnd *cmd)
-{
-	int i, s;
-	unsigned char *command;
-	printk("scsi%d: destination target %d, lun %llu\n",
-		H_NO(cmd), cmd->device->id, cmd->device->lun);
-	printk(KERN_CONT "        command = ");
-	command = cmd->cmnd;
-	printk(KERN_CONT "%2d (0x%02x)", command[0], command[0]);
-	for (i = 1, s = COMMAND_SIZE(command[0]); i < s; ++i)
-		printk(KERN_CONT " %02x", command[i]);
-	printk("\n");
-}
-
-static void __maybe_unused NCR5380_print_status(struct Scsi_Host *instance)
-{
-	struct NCR5380_hostdata *hostdata;
-	struct scsi_cmnd *ptr;
-
-	NCR5380_dprint(NDEBUG_ANY, instance);
-	NCR5380_dprint_phase(NDEBUG_ANY, instance);
-
-	hostdata = (struct NCR5380_hostdata *)instance->hostdata;
-
-	if (!hostdata->connected)
-		printk("scsi%d: no currently connected command\n", HOSTNO);
-	else
-		lprint_Scsi_Cmnd((struct scsi_cmnd *) hostdata->connected);
-	printk("scsi%d: issue_queue\n", HOSTNO);
-	for (ptr = (struct scsi_cmnd *)hostdata->issue_queue; ptr; ptr = NEXT(ptr))
-		lprint_Scsi_Cmnd(ptr);
-
-	printk("scsi%d: disconnected_queue\n", HOSTNO);
-	for (ptr = (struct scsi_cmnd *) hostdata->disconnected_queue; ptr;
-	     ptr = NEXT(ptr))
-		lprint_Scsi_Cmnd(ptr);
-	printk("\n");
-}
-
-static void show_Scsi_Cmnd(struct scsi_cmnd *cmd, struct seq_file *m)
-{
-	int i, s;
-	unsigned char *command;
-	seq_printf(m, "scsi%d: destination target %d, lun %llu\n",
-		H_NO(cmd), cmd->device->id, cmd->device->lun);
-	seq_puts(m, "        command = ");
-	command = cmd->cmnd;
-	seq_printf(m, "%2d (0x%02x)", command[0], command[0]);
-	for (i = 1, s = COMMAND_SIZE(command[0]); i < s; ++i)
-		seq_printf(m, " %02x", command[i]);
-	seq_putc(m, '\n');
-}
-
-static int __maybe_unused NCR5380_show_info(struct seq_file *m,
-                                            struct Scsi_Host *instance)
-{
-	struct NCR5380_hostdata *hostdata;
-	struct scsi_cmnd *ptr;
-	unsigned long flags;
-
-	hostdata = (struct NCR5380_hostdata *)instance->hostdata;
-
-	spin_lock_irqsave(&hostdata->lock, flags);
-	if (!hostdata->connected)
-		seq_printf(m, "scsi%d: no currently connected command\n", HOSTNO);
-	else
-		show_Scsi_Cmnd((struct scsi_cmnd *) hostdata->connected, m);
-	seq_printf(m, "scsi%d: issue_queue\n", HOSTNO);
-	for (ptr = (struct scsi_cmnd *)hostdata->issue_queue; ptr; ptr = NEXT(ptr))
-		show_Scsi_Cmnd(ptr, m);
-
-	seq_printf(m, "scsi%d: disconnected_queue\n", HOSTNO);
-	for (ptr = (struct scsi_cmnd *) hostdata->disconnected_queue; ptr;
-	     ptr = NEXT(ptr))
-		show_Scsi_Cmnd(ptr, m);
-
-	spin_unlock_irqrestore(&hostdata->lock, flags);
-	return 0;
-}
-
-/**
  * NCR5380_init - initialise an NCR5380
  * @instance: adapter to configure
  * @flags: control flags
@@ -2627,7 +2539,8 @@ int NCR5380_abort(struct scsi_cmnd *cmd)
 
 	spin_lock_irqsave(&hostdata->lock, flags);
 
-	NCR5380_print_status(instance);
+	NCR5380_dprint(NDEBUG_ANY, instance);
+	NCR5380_dprint_phase(NDEBUG_ANY, instance);
 
 	dprintk(NDEBUG_ABORT, "scsi%d: abort called basr 0x%02x, sr 0x%02x\n", HOSTNO,
 		    NCR5380_read(BUS_AND_STATUS_REG),
@@ -2825,8 +2738,9 @@ static int NCR5380_bus_reset(struct scsi
 
 #if (NDEBUG & NDEBUG_ANY)
 	scmd_printk(KERN_INFO, cmd, "performing bus reset\n");
-	NCR5380_print_status(instance);
 #endif
+	NCR5380_dprint(NDEBUG_ANY, instance);
+	NCR5380_dprint_phase(NDEBUG_ANY, instance);
 
 	do_reset(instance);
 
Index: linux/drivers/scsi/arm/oak.c
===================================================================
--- linux.orig/drivers/scsi/arm/oak.c	2015-11-18 19:34:01.000000000 +1100
+++ linux/drivers/scsi/arm/oak.c	2015-11-18 19:34:12.000000000 +1100
@@ -28,7 +28,6 @@
 
 #define NCR5380_queue_command		oakscsi_queue_command
 #define NCR5380_info			oakscsi_info
-#define NCR5380_show_info		oakscsi_show_info
 
 #define NCR5380_implementation_fields	\
 	void __iomem *base
@@ -104,7 +103,6 @@ printk("reading %p len %d\n", addr, len)
 
 static struct scsi_host_template oakscsi_template = {
 	.module			= THIS_MODULE,
-	.show_info		= oakscsi_show_info,
 	.name			= "Oak 16-bit SCSI",
 	.info			= oakscsi_info,
 	.queuecommand		= oakscsi_queue_command,
Index: linux/drivers/scsi/atari_scsi.c
===================================================================
--- linux.orig/drivers/scsi/atari_scsi.c	2015-11-18 19:34:05.000000000 +1100
+++ linux/drivers/scsi/atari_scsi.c	2015-11-18 19:34:12.000000000 +1100
@@ -97,7 +97,6 @@
 
 #define NCR5380_queue_command           atari_scsi_queue_command
 #define NCR5380_abort                   atari_scsi_abort
-#define NCR5380_show_info               atari_scsi_show_info
 #define NCR5380_info                    atari_scsi_info
 
 #define NCR5380_dma_read_setup(instance, data, count) \
@@ -774,7 +773,6 @@ static int atari_scsi_bus_reset(struct s
 static struct scsi_host_template atari_scsi_template = {
 	.module			= THIS_MODULE,
 	.proc_name		= DRV_MODULE_NAME,
-	.show_info		= atari_scsi_show_info,
 	.name			= "Atari native SCSI",
 	.info			= atari_scsi_info,
 	.queuecommand		= atari_scsi_queue_command,
Index: linux/drivers/scsi/g_NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/g_NCR5380.c	2015-11-18 19:34:05.000000000 +1100
+++ linux/drivers/scsi/g_NCR5380.c	2015-11-18 19:34:12.000000000 +1100
@@ -716,7 +716,6 @@ static int generic_NCR5380_dma_xfer_len(
 
 static struct scsi_host_template driver_template = {
 	.proc_name		= DRV_MODULE_NAME,
-	.show_info		= generic_NCR5380_show_info,
 	.name			= "Generic NCR5380/NCR53C400 SCSI",
 	.detect			= generic_NCR5380_detect,
 	.release		= generic_NCR5380_release_resources,
Index: linux/drivers/scsi/sun3_scsi.c
===================================================================
--- linux.orig/drivers/scsi/sun3_scsi.c	2015-11-18 19:34:05.000000000 +1100
+++ linux/drivers/scsi/sun3_scsi.c	2015-11-18 19:34:12.000000000 +1100
@@ -53,7 +53,6 @@
 #define NCR5380_queue_command           sun3scsi_queue_command
 #define NCR5380_bus_reset               sun3scsi_bus_reset
 #define NCR5380_abort                   sun3scsi_abort
-#define NCR5380_show_info               sun3scsi_show_info
 #define NCR5380_info                    sun3scsi_info
 
 #define NCR5380_dma_read_setup(instance, data, count) \
@@ -459,7 +458,6 @@ static int sun3scsi_dma_finish(int write
 static struct scsi_host_template sun3_scsi_template = {
 	.module			= THIS_MODULE,
 	.proc_name		= DRV_MODULE_NAME,
-	.show_info		= sun3scsi_show_info,
 	.name			= SUN3_SCSI_NAME,
 	.info			= sun3scsi_info,
 	.queuecommand		= sun3scsi_queue_command,



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

* [PATCH 51/71] ncr5380: Remove command list debug code
@ 2015-11-18  8:35   ` Finn Thain
  0 siblings, 0 replies; 268+ messages in thread
From: Finn Thain @ 2015-11-18  8:35 UTC (permalink / raw)
  To: James E.J. Bottomley, Michael Schmitz, linux-m68k, linux-scsi,
	linux-kernel, Russell King, linux-arm-kernel

[-- Attachment #1: ncr5380-remove-cmd-list-debug-code --]
[-- Type: text/plain, Size: 11700 bytes --]

Some NCR5380 hosts offer a .show_info method to access the contents of
the various command list data structures from a procfs file. When NDEBUG
is set, the same information is sent to the console during EH.

The two core drivers, atari_NCR5380.c and NCR5380.c differ here. Because
it is just for debugging, the easiest way to fix the discrepancy is
simply remove this code.

The only remaining users of NCR5380_show_info() and NCR5380_write_info()
are drivers that define PSEUDO_DMA. The others have no use for the
.show_info method, so don't initialize it.

Signed-off-by: Finn Thain <fthain@telegraphics.com.au>

---
 drivers/scsi/NCR5380.c       |   70 ++------------------------------
 drivers/scsi/arm/oak.c       |    2 
 drivers/scsi/atari_NCR5380.c |   94 +------------------------------------------
 drivers/scsi/atari_scsi.c    |    2 
 drivers/scsi/g_NCR5380.c     |    1 
 drivers/scsi/sun3_scsi.c     |    2 
 6 files changed, 9 insertions(+), 162 deletions(-)

Index: linux/drivers/scsi/NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/NCR5380.c	2015-11-18 19:34:10.000000000 +1100
+++ linux/drivers/scsi/NCR5380.c	2015-11-18 19:34:12.000000000 +1100
@@ -570,22 +570,6 @@ static void prepare_info(struct Scsi_Hos
 	         "");
 }
 
-/**
- *	NCR5380_print_status 	-	dump controller info
- *	@instance: controller to dump
- *
- *	Print commands in the various queues, called from NCR5380_abort 
- *	and NCR5380_debug to aid debugging.
- *
- *	Locks: called functions disable irqs
- */
-
-static void __maybe_unused NCR5380_print_status(struct Scsi_Host *instance)
-{
-	NCR5380_dprint(NDEBUG_ANY, instance);
-	NCR5380_dprint_phase(NDEBUG_ANY, instance);
-}
-
 #ifdef PSEUDO_DMA
 /******************************************/
 /*
@@ -610,65 +594,19 @@ static int __maybe_unused NCR5380_write_
 	hostdata->spin_max_w = 0;
 	return 0;
 }
-#endif
-
-static
-void lprint_Scsi_Cmnd(struct scsi_cmnd *cmd, struct seq_file *m);
-static
-void lprint_command(unsigned char *cmd, struct seq_file *m);
-static
-void lprint_opcode(int opcode, struct seq_file *m);
 
 static int __maybe_unused NCR5380_show_info(struct seq_file *m,
 	struct Scsi_Host *instance)
 {
 	struct NCR5380_hostdata *hostdata;
-	struct scsi_cmnd *ptr;
-	unsigned long flags;
 
 	hostdata = (struct NCR5380_hostdata *) instance->hostdata;
 
-#ifdef PSEUDO_DMA
 	seq_printf(m, "Highwater I/O busy spin counts: write %d, read %d\n",
 	        hostdata->spin_max_w, hostdata->spin_max_r);
-#endif
-	spin_lock_irqsave(&hostdata->lock, flags);
-	if (!hostdata->connected)
-		seq_printf(m, "scsi%d: no currently connected command\n", instance->host_no);
-	else
-		lprint_Scsi_Cmnd((struct scsi_cmnd *) hostdata->connected, m);
-	seq_printf(m, "scsi%d: issue_queue\n", instance->host_no);
-	for (ptr = (struct scsi_cmnd *) hostdata->issue_queue; ptr; ptr = (struct scsi_cmnd *) ptr->host_scribble)
-		lprint_Scsi_Cmnd(ptr, m);
-
-	seq_printf(m, "scsi%d: disconnected_queue\n", instance->host_no);
-	for (ptr = (struct scsi_cmnd *) hostdata->disconnected_queue; ptr; ptr = (struct scsi_cmnd *) ptr->host_scribble)
-		lprint_Scsi_Cmnd(ptr, m);
-	spin_unlock_irqrestore(&hostdata->lock, flags);
 	return 0;
 }
-
-static void lprint_Scsi_Cmnd(struct scsi_cmnd *cmd, struct seq_file *m)
-{
-	seq_printf(m, "scsi%d : destination target %d, lun %llu\n", cmd->device->host->host_no, cmd->device->id, cmd->device->lun);
-	seq_puts(m, "        command = ");
-	lprint_command(cmd->cmnd, m);
-}
-
-static void lprint_command(unsigned char *command, struct seq_file *m)
-{
-	int i, s;
-	lprint_opcode(command[0], m);
-	for (i = 1, s = COMMAND_SIZE(command[0]); i < s; ++i)
-		seq_printf(m, "%02x ", command[i]);
-	seq_putc(m, '\n');
-}
-
-static void lprint_opcode(int opcode, struct seq_file *m)
-{
-	seq_printf(m, "%2d (0x%02x)", opcode, opcode);
-}
-
+#endif
 
 /**
  *	NCR5380_init	-	initialise an NCR5380
@@ -2342,7 +2280,8 @@ static int NCR5380_abort(struct scsi_cmn
 
 	spin_lock_irqsave(&hostdata->lock, flags);
 
-	NCR5380_print_status(instance);
+	NCR5380_dprint(NDEBUG_ANY, instance);
+	NCR5380_dprint_phase(NDEBUG_ANY, instance);
 
 	dprintk(NDEBUG_ABORT, "scsi%d : abort called\n", instance->host_no);
 	dprintk(NDEBUG_ABORT, "        basr 0x%X, sr 0x%X\n", NCR5380_read(BUS_AND_STATUS_REG), NCR5380_read(STATUS_REG));
@@ -2497,8 +2436,9 @@ static int NCR5380_bus_reset(struct scsi
 
 #if (NDEBUG & NDEBUG_ANY)
 	scmd_printk(KERN_INFO, cmd, "performing bus reset\n");
-	NCR5380_print_status(instance);
 #endif
+	NCR5380_dprint(NDEBUG_ANY, instance);
+	NCR5380_dprint_phase(NDEBUG_ANY, instance);
 
 	do_reset(instance);
 
Index: linux/drivers/scsi/atari_NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/atari_NCR5380.c	2015-11-18 19:34:10.000000000 +1100
+++ linux/drivers/scsi/atari_NCR5380.c	2015-11-18 19:34:12.000000000 +1100
@@ -669,94 +669,6 @@ static void prepare_info(struct Scsi_Hos
 }
 
 /**
- * NCR5380_print_status - dump controller info
- * @instance: controller to dump
- *
- * Print commands in the various queues, called from NCR5380_abort
- * to aid debugging.
- */
-
-static void lprint_Scsi_Cmnd(struct scsi_cmnd *cmd)
-{
-	int i, s;
-	unsigned char *command;
-	printk("scsi%d: destination target %d, lun %llu\n",
-		H_NO(cmd), cmd->device->id, cmd->device->lun);
-	printk(KERN_CONT "        command = ");
-	command = cmd->cmnd;
-	printk(KERN_CONT "%2d (0x%02x)", command[0], command[0]);
-	for (i = 1, s = COMMAND_SIZE(command[0]); i < s; ++i)
-		printk(KERN_CONT " %02x", command[i]);
-	printk("\n");
-}
-
-static void __maybe_unused NCR5380_print_status(struct Scsi_Host *instance)
-{
-	struct NCR5380_hostdata *hostdata;
-	struct scsi_cmnd *ptr;
-
-	NCR5380_dprint(NDEBUG_ANY, instance);
-	NCR5380_dprint_phase(NDEBUG_ANY, instance);
-
-	hostdata = (struct NCR5380_hostdata *)instance->hostdata;
-
-	if (!hostdata->connected)
-		printk("scsi%d: no currently connected command\n", HOSTNO);
-	else
-		lprint_Scsi_Cmnd((struct scsi_cmnd *) hostdata->connected);
-	printk("scsi%d: issue_queue\n", HOSTNO);
-	for (ptr = (struct scsi_cmnd *)hostdata->issue_queue; ptr; ptr = NEXT(ptr))
-		lprint_Scsi_Cmnd(ptr);
-
-	printk("scsi%d: disconnected_queue\n", HOSTNO);
-	for (ptr = (struct scsi_cmnd *) hostdata->disconnected_queue; ptr;
-	     ptr = NEXT(ptr))
-		lprint_Scsi_Cmnd(ptr);
-	printk("\n");
-}
-
-static void show_Scsi_Cmnd(struct scsi_cmnd *cmd, struct seq_file *m)
-{
-	int i, s;
-	unsigned char *command;
-	seq_printf(m, "scsi%d: destination target %d, lun %llu\n",
-		H_NO(cmd), cmd->device->id, cmd->device->lun);
-	seq_puts(m, "        command = ");
-	command = cmd->cmnd;
-	seq_printf(m, "%2d (0x%02x)", command[0], command[0]);
-	for (i = 1, s = COMMAND_SIZE(command[0]); i < s; ++i)
-		seq_printf(m, " %02x", command[i]);
-	seq_putc(m, '\n');
-}
-
-static int __maybe_unused NCR5380_show_info(struct seq_file *m,
-                                            struct Scsi_Host *instance)
-{
-	struct NCR5380_hostdata *hostdata;
-	struct scsi_cmnd *ptr;
-	unsigned long flags;
-
-	hostdata = (struct NCR5380_hostdata *)instance->hostdata;
-
-	spin_lock_irqsave(&hostdata->lock, flags);
-	if (!hostdata->connected)
-		seq_printf(m, "scsi%d: no currently connected command\n", HOSTNO);
-	else
-		show_Scsi_Cmnd((struct scsi_cmnd *) hostdata->connected, m);
-	seq_printf(m, "scsi%d: issue_queue\n", HOSTNO);
-	for (ptr = (struct scsi_cmnd *)hostdata->issue_queue; ptr; ptr = NEXT(ptr))
-		show_Scsi_Cmnd(ptr, m);
-
-	seq_printf(m, "scsi%d: disconnected_queue\n", HOSTNO);
-	for (ptr = (struct scsi_cmnd *) hostdata->disconnected_queue; ptr;
-	     ptr = NEXT(ptr))
-		show_Scsi_Cmnd(ptr, m);
-
-	spin_unlock_irqrestore(&hostdata->lock, flags);
-	return 0;
-}
-
-/**
  * NCR5380_init - initialise an NCR5380
  * @instance: adapter to configure
  * @flags: control flags
@@ -2627,7 +2539,8 @@ int NCR5380_abort(struct scsi_cmnd *cmd)
 
 	spin_lock_irqsave(&hostdata->lock, flags);
 
-	NCR5380_print_status(instance);
+	NCR5380_dprint(NDEBUG_ANY, instance);
+	NCR5380_dprint_phase(NDEBUG_ANY, instance);
 
 	dprintk(NDEBUG_ABORT, "scsi%d: abort called basr 0x%02x, sr 0x%02x\n", HOSTNO,
 		    NCR5380_read(BUS_AND_STATUS_REG),
@@ -2825,8 +2738,9 @@ static int NCR5380_bus_reset(struct scsi
 
 #if (NDEBUG & NDEBUG_ANY)
 	scmd_printk(KERN_INFO, cmd, "performing bus reset\n");
-	NCR5380_print_status(instance);
 #endif
+	NCR5380_dprint(NDEBUG_ANY, instance);
+	NCR5380_dprint_phase(NDEBUG_ANY, instance);
 
 	do_reset(instance);
 
Index: linux/drivers/scsi/arm/oak.c
===================================================================
--- linux.orig/drivers/scsi/arm/oak.c	2015-11-18 19:34:01.000000000 +1100
+++ linux/drivers/scsi/arm/oak.c	2015-11-18 19:34:12.000000000 +1100
@@ -28,7 +28,6 @@
 
 #define NCR5380_queue_command		oakscsi_queue_command
 #define NCR5380_info			oakscsi_info
-#define NCR5380_show_info		oakscsi_show_info
 
 #define NCR5380_implementation_fields	\
 	void __iomem *base
@@ -104,7 +103,6 @@ printk("reading %p len %d\n", addr, len)
 
 static struct scsi_host_template oakscsi_template = {
 	.module			= THIS_MODULE,
-	.show_info		= oakscsi_show_info,
 	.name			= "Oak 16-bit SCSI",
 	.info			= oakscsi_info,
 	.queuecommand		= oakscsi_queue_command,
Index: linux/drivers/scsi/atari_scsi.c
===================================================================
--- linux.orig/drivers/scsi/atari_scsi.c	2015-11-18 19:34:05.000000000 +1100
+++ linux/drivers/scsi/atari_scsi.c	2015-11-18 19:34:12.000000000 +1100
@@ -97,7 +97,6 @@
 
 #define NCR5380_queue_command           atari_scsi_queue_command
 #define NCR5380_abort                   atari_scsi_abort
-#define NCR5380_show_info               atari_scsi_show_info
 #define NCR5380_info                    atari_scsi_info
 
 #define NCR5380_dma_read_setup(instance, data, count) \
@@ -774,7 +773,6 @@ static int atari_scsi_bus_reset(struct s
 static struct scsi_host_template atari_scsi_template = {
 	.module			= THIS_MODULE,
 	.proc_name		= DRV_MODULE_NAME,
-	.show_info		= atari_scsi_show_info,
 	.name			= "Atari native SCSI",
 	.info			= atari_scsi_info,
 	.queuecommand		= atari_scsi_queue_command,
Index: linux/drivers/scsi/g_NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/g_NCR5380.c	2015-11-18 19:34:05.000000000 +1100
+++ linux/drivers/scsi/g_NCR5380.c	2015-11-18 19:34:12.000000000 +1100
@@ -716,7 +716,6 @@ static int generic_NCR5380_dma_xfer_len(
 
 static struct scsi_host_template driver_template = {
 	.proc_name		= DRV_MODULE_NAME,
-	.show_info		= generic_NCR5380_show_info,
 	.name			= "Generic NCR5380/NCR53C400 SCSI",
 	.detect			= generic_NCR5380_detect,
 	.release		= generic_NCR5380_release_resources,
Index: linux/drivers/scsi/sun3_scsi.c
===================================================================
--- linux.orig/drivers/scsi/sun3_scsi.c	2015-11-18 19:34:05.000000000 +1100
+++ linux/drivers/scsi/sun3_scsi.c	2015-11-18 19:34:12.000000000 +1100
@@ -53,7 +53,6 @@
 #define NCR5380_queue_command           sun3scsi_queue_command
 #define NCR5380_bus_reset               sun3scsi_bus_reset
 #define NCR5380_abort                   sun3scsi_abort
-#define NCR5380_show_info               sun3scsi_show_info
 #define NCR5380_info                    sun3scsi_info
 
 #define NCR5380_dma_read_setup(instance, data, count) \
@@ -459,7 +458,6 @@ static int sun3scsi_dma_finish(int write
 static struct scsi_host_template sun3_scsi_template = {
 	.module			= THIS_MODULE,
 	.proc_name		= DRV_MODULE_NAME,
-	.show_info		= sun3scsi_show_info,
 	.name			= SUN3_SCSI_NAME,
 	.info			= sun3scsi_info,
 	.queuecommand		= sun3scsi_queue_command,

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

* [PATCH 51/71] ncr5380: Remove command list debug code
@ 2015-11-18  8:35   ` Finn Thain
  0 siblings, 0 replies; 268+ messages in thread
From: Finn Thain @ 2015-11-18  8:35 UTC (permalink / raw)
  To: linux-arm-kernel

An embedded and charset-unspecified text was scrubbed...
Name: ncr5380-remove-cmd-list-debug-code
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20151118/9db1a415/attachment.ksh>

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

* [PATCH 52/71] ncr5380: Remove H_NO macro and introduce dsprintk
  2015-11-18  8:34 ` Finn Thain
@ 2015-11-18  8:35   ` Finn Thain
  -1 siblings, 0 replies; 268+ messages in thread
From: Finn Thain @ 2015-11-18  8:35 UTC (permalink / raw)
  To: James E.J. Bottomley, Michael Schmitz, linux-m68k, linux-scsi,
	linux-kernel

[-- Attachment #1: atari_NCR5380-remove-H_NO-and-introduce-dsprintk --]
[-- Type: text/plain, Size: 9770 bytes --]

Replace all H_NO and some HOSTNO macros (both peculiar to atari_NCR5380.c)
with a new dsprintk macro that's more useful and more consistent. The new
macro avoids a lot of boilerplate in new code in subsequent patches. Keep
NCR5380.c in sync. Remaining HOSTNO macros are removed as side-effects
of subsequent patches.

Signed-off-by: Finn Thain <fthain@telegraphics.com.au>

---
 drivers/scsi/NCR5380.c       |   11 +++++---
 drivers/scsi/NCR5380.h       |    5 +++
 drivers/scsi/atari_NCR5380.c |   57 +++++++++++++++++++++----------------------
 3 files changed, 40 insertions(+), 33 deletions(-)

Index: linux/drivers/scsi/NCR5380.h
===================================================================
--- linux.orig/drivers/scsi/NCR5380.h	2015-11-18 19:34:10.000000000 +1100
+++ linux/drivers/scsi/NCR5380.h	2015-11-18 19:34:14.000000000 +1100
@@ -285,6 +285,11 @@ struct NCR5380_hostdata {
 	do { if ((NDEBUG) & (flg)) \
 		printk(KERN_DEBUG fmt, ## __VA_ARGS__); } while (0)
 
+#define dsprintk(flg, host, fmt, ...) \
+	do { if ((NDEBUG) & (flg)) \
+		shost_printk(KERN_DEBUG, host, fmt, ## __VA_ARGS__); \
+	} while (0)
+
 #if NDEBUG
 #define NCR5380_dprint(flg, arg) \
 	do { if ((NDEBUG) & (flg)) NCR5380_print(arg); } while (0)
Index: linux/drivers/scsi/atari_NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/atari_NCR5380.c	2015-11-18 19:34:12.000000000 +1100
+++ linux/drivers/scsi/atari_NCR5380.c	2015-11-18 19:34:14.000000000 +1100
@@ -207,7 +207,6 @@
 #define	NEXTADDR(cmd)		((struct scsi_cmnd **)&(cmd)->host_scribble)
 
 #define	HOSTNO		instance->host_no
-#define	H_NO(cmd)	(cmd)->device->host->host_no
 
 static int do_abort(struct Scsi_Host *);
 static void do_reset(struct Scsi_Host *);
@@ -280,7 +279,8 @@ static void __init init_tags(struct NCR5
 static int is_lun_busy(struct scsi_cmnd *cmd, int should_be_tagged)
 {
 	u8 lun = cmd->device->lun;
-	SETUP_HOSTDATA(cmd->device->host);
+	struct Scsi_Host *instance = cmd->device->host;
+	struct NCR5380_hostdata *hostdata = shost_priv(instance);
 
 	if (hostdata->busy[cmd->device->id] & (1 << lun))
 		return 1;
@@ -290,8 +290,8 @@ static int is_lun_busy(struct scsi_cmnd
 		return 0;
 	if (hostdata->TagAlloc[scmd_id(cmd)][lun].nr_allocated >=
 	    hostdata->TagAlloc[scmd_id(cmd)][lun].queue_size) {
-		dprintk(NDEBUG_TAGS, "scsi%d: target %d lun %d: no free tags\n",
-			   H_NO(cmd), cmd->device->id, lun);
+		dsprintk(NDEBUG_TAGS, instance, "target %d lun %d: no free tags\n",
+		         scmd_id(cmd), lun);
 		return 1;
 	}
 	return 0;
@@ -306,7 +306,8 @@ static int is_lun_busy(struct scsi_cmnd
 static void cmd_get_tag(struct scsi_cmnd *cmd, int should_be_tagged)
 {
 	u8 lun = cmd->device->lun;
-	SETUP_HOSTDATA(cmd->device->host);
+	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.
@@ -316,18 +317,16 @@ static void cmd_get_tag(struct scsi_cmnd
 	    !cmd->device->tagged_supported) {
 		cmd->tag = TAG_NONE;
 		hostdata->busy[cmd->device->id] |= (1 << lun);
-		dprintk(NDEBUG_TAGS, "scsi%d: target %d lun %d now allocated by untagged "
-			   "command\n", H_NO(cmd), cmd->device->id, 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++;
-		dprintk(NDEBUG_TAGS, "scsi%d: using tag %d for target %d lun %d "
-			   "(now %d tags in use)\n",
-			   H_NO(cmd), cmd->tag, cmd->device->id,
-			   lun, 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);
 	}
 }
 
@@ -339,21 +338,22 @@ static void cmd_get_tag(struct scsi_cmnd
 static void cmd_free_tag(struct scsi_cmnd *cmd)
 {
 	u8 lun = cmd->device->lun;
-	SETUP_HOSTDATA(cmd->device->host);
+	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);
-		dprintk(NDEBUG_TAGS, "scsi%d: target %d lun %d untagged cmd finished\n",
-			   H_NO(cmd), cmd->device->id, lun);
+		dsprintk(NDEBUG_TAGS, instance, "target %d lun %d untagged cmd freed\n",
+		         scmd_id(cmd), lun);
 	} else if (cmd->tag >= MAX_TAGS) {
-		printk(KERN_NOTICE "scsi%d: trying to free bad tag %d!\n",
-		       H_NO(cmd), cmd->tag);
+		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--;
-		dprintk(NDEBUG_TAGS, "scsi%d: freed tag %d for target %d lun %d\n",
-			   H_NO(cmd), cmd->tag, cmd->device->id, lun);
+		dsprintk(NDEBUG_TAGS, instance, "freed tag %d for target %d lun %d\n",
+		         cmd->tag, scmd_id(cmd), lun);
 	}
 }
 
@@ -812,8 +812,7 @@ static int NCR5380_queue_command(struct
 	switch (cmd->cmnd[0]) {
 	case WRITE_6:
 	case WRITE_10:
-		printk(KERN_NOTICE "scsi%d: WRITE attempted with NO_WRITE debugging flag set\n",
-		       H_NO(cmd));
+		shost_printk(KERN_DEBUG, instance, "WRITE attempted with NDEBUG_NO_WRITE set\n");
 		cmd->result = (DID_ERROR << 16);
 		cmd->scsi_done(cmd);
 		return 0;
@@ -872,8 +871,8 @@ static int NCR5380_queue_command(struct
 	}
 	spin_unlock_irqrestore(&hostdata->lock, flags);
 
-	dprintk(NDEBUG_QUEUES, "scsi%d: command added to %s of queue\n", H_NO(cmd),
-		  (cmd->cmnd[0] == REQUEST_SENSE) ? "head" : "tail");
+	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);
@@ -1319,8 +1318,7 @@ static int NCR5380_select(struct Scsi_Ho
 	    (NCR5380_read(INITIATOR_COMMAND_REG) & ICR_ARBITRATION_LOST)) {
 		NCR5380_write(MODE_REG, MR_BASE);
 		NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
-		dprintk(NDEBUG_ARBITRATION, "scsi%d: lost arbitration, deasserting ICR_ASSERT_SEL\n",
-			   HOSTNO);
+		dsprintk(NDEBUG_ARBITRATION, instance, "arbitration lost, negating SEL\n");
 		spin_lock_irq(&hostdata->lock);
 		return -1;
 	}
@@ -2089,8 +2087,9 @@ static void NCR5380_information_transfer
 						LIST(cmd,hostdata->issue_queue);
 						SET_NEXT(cmd, hostdata->issue_queue);
 						hostdata->issue_queue = (struct scsi_cmnd *) cmd;
-						dprintk(NDEBUG_QUEUES, "scsi%d: REQUEST SENSE added to head of "
-							  "issue queue\n", H_NO(cmd));
+						dsprintk(NDEBUG_QUEUES, instance,
+						         "REQUEST SENSE cmd %p added to head of issue queue\n",
+						         cmd);
 					} else {
 						cmd->scsi_done(cmd);
 					}
@@ -2756,11 +2755,11 @@ static int NCR5380_bus_reset(struct scsi
 	 */
 
 	if (hostdata->issue_queue)
-		dprintk(NDEBUG_ABORT, "scsi%d: reset aborted issued command(s)\n", H_NO(cmd));
+		dsprintk(NDEBUG_ABORT, instance, "reset aborted issued command(s)\n");
 	if (hostdata->connected)
-		dprintk(NDEBUG_ABORT, "scsi%d: reset aborted a connected command\n", H_NO(cmd));
+		dsprintk(NDEBUG_ABORT, instance, "reset aborted a connected command\n");
 	if (hostdata->disconnected_queue)
-		dprintk(NDEBUG_ABORT, "scsi%d: reset aborted disconnected command(s)\n", H_NO(cmd));
+		dsprintk(NDEBUG_ABORT, instance, "reset aborted disconnected command(s)\n");
 
 	hostdata->issue_queue = NULL;
 	hostdata->connected = NULL;
Index: linux/drivers/scsi/NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/NCR5380.c	2015-11-18 19:34:12.000000000 +1100
+++ linux/drivers/scsi/NCR5380.c	2015-11-18 19:34:14.000000000 +1100
@@ -751,7 +751,7 @@ static int NCR5380_queue_command(struct
 	switch (cmd->cmnd[0]) {
 	case WRITE_6:
 	case WRITE_10:
-		printk("scsi%d : WRITE attempted with NO_WRITE debugging flag set\n", instance->host_no);
+		shost_printk(KERN_DEBUG, instance, "WRITE attempted with NDEBUG_NO_WRITE set\n");
 		cmd->result = (DID_ERROR << 16);
 		cmd->scsi_done(cmd);
 		return 0;
@@ -786,7 +786,8 @@ static int NCR5380_queue_command(struct
 	}
 	spin_unlock_irqrestore(&hostdata->lock, flags);
 
-	dprintk(NDEBUG_QUEUES, "scsi%d : command added to %s of queue\n", instance->host_no, (cmd->cmnd[0] == REQUEST_SENSE) ? "head" : "tail");
+	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);
@@ -1101,7 +1102,7 @@ static int NCR5380_select(struct Scsi_Ho
 	    (NCR5380_read(INITIATOR_COMMAND_REG) & ICR_ARBITRATION_LOST)) {
 		NCR5380_write(MODE_REG, MR_BASE);
 		NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
-		dprintk(NDEBUG_ARBITRATION, "scsi%d : lost arbitration, deasserting ICR_ASSERT_SEL\n", instance->host_no);
+		dsprintk(NDEBUG_ARBITRATION, instance, "arbitration lost, negating SEL\n");
 		spin_lock_irq(&hostdata->lock);
 		return -1;
 	}
@@ -1895,7 +1896,9 @@ static void NCR5380_information_transfer
 						cmd->host_scribble = (unsigned char *)
 						    hostdata->issue_queue;
 						hostdata->issue_queue = (struct scsi_cmnd *) cmd;
-						dprintk(NDEBUG_QUEUES, "scsi%d : REQUEST SENSE added to head of issue queue\n", instance->host_no);
+						dsprintk(NDEBUG_QUEUES, instance,
+						         "REQUEST SENSE cmd %p added to head of issue queue\n",
+						         cmd);
 					} else {
 						cmd->scsi_done(cmd);
 					}



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

* [PATCH 52/71] ncr5380: Remove H_NO macro and introduce dsprintk
@ 2015-11-18  8:35   ` Finn Thain
  0 siblings, 0 replies; 268+ messages in thread
From: Finn Thain @ 2015-11-18  8:35 UTC (permalink / raw)
  To: James E.J. Bottomley, Michael Schmitz, linux-m68k, linux-scsi,
	linux-kernel

[-- Attachment #1: atari_NCR5380-remove-H_NO-and-introduce-dsprintk --]
[-- Type: text/plain, Size: 9770 bytes --]

Replace all H_NO and some HOSTNO macros (both peculiar to atari_NCR5380.c)
with a new dsprintk macro that's more useful and more consistent. The new
macro avoids a lot of boilerplate in new code in subsequent patches. Keep
NCR5380.c in sync. Remaining HOSTNO macros are removed as side-effects
of subsequent patches.

Signed-off-by: Finn Thain <fthain@telegraphics.com.au>

---
 drivers/scsi/NCR5380.c       |   11 +++++---
 drivers/scsi/NCR5380.h       |    5 +++
 drivers/scsi/atari_NCR5380.c |   57 +++++++++++++++++++++----------------------
 3 files changed, 40 insertions(+), 33 deletions(-)

Index: linux/drivers/scsi/NCR5380.h
===================================================================
--- linux.orig/drivers/scsi/NCR5380.h	2015-11-18 19:34:10.000000000 +1100
+++ linux/drivers/scsi/NCR5380.h	2015-11-18 19:34:14.000000000 +1100
@@ -285,6 +285,11 @@ struct NCR5380_hostdata {
 	do { if ((NDEBUG) & (flg)) \
 		printk(KERN_DEBUG fmt, ## __VA_ARGS__); } while (0)
 
+#define dsprintk(flg, host, fmt, ...) \
+	do { if ((NDEBUG) & (flg)) \
+		shost_printk(KERN_DEBUG, host, fmt, ## __VA_ARGS__); \
+	} while (0)
+
 #if NDEBUG
 #define NCR5380_dprint(flg, arg) \
 	do { if ((NDEBUG) & (flg)) NCR5380_print(arg); } while (0)
Index: linux/drivers/scsi/atari_NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/atari_NCR5380.c	2015-11-18 19:34:12.000000000 +1100
+++ linux/drivers/scsi/atari_NCR5380.c	2015-11-18 19:34:14.000000000 +1100
@@ -207,7 +207,6 @@
 #define	NEXTADDR(cmd)		((struct scsi_cmnd **)&(cmd)->host_scribble)
 
 #define	HOSTNO		instance->host_no
-#define	H_NO(cmd)	(cmd)->device->host->host_no
 
 static int do_abort(struct Scsi_Host *);
 static void do_reset(struct Scsi_Host *);
@@ -280,7 +279,8 @@ static void __init init_tags(struct NCR5
 static int is_lun_busy(struct scsi_cmnd *cmd, int should_be_tagged)
 {
 	u8 lun = cmd->device->lun;
-	SETUP_HOSTDATA(cmd->device->host);
+	struct Scsi_Host *instance = cmd->device->host;
+	struct NCR5380_hostdata *hostdata = shost_priv(instance);
 
 	if (hostdata->busy[cmd->device->id] & (1 << lun))
 		return 1;
@@ -290,8 +290,8 @@ static int is_lun_busy(struct scsi_cmnd
 		return 0;
 	if (hostdata->TagAlloc[scmd_id(cmd)][lun].nr_allocated >=
 	    hostdata->TagAlloc[scmd_id(cmd)][lun].queue_size) {
-		dprintk(NDEBUG_TAGS, "scsi%d: target %d lun %d: no free tags\n",
-			   H_NO(cmd), cmd->device->id, lun);
+		dsprintk(NDEBUG_TAGS, instance, "target %d lun %d: no free tags\n",
+		         scmd_id(cmd), lun);
 		return 1;
 	}
 	return 0;
@@ -306,7 +306,8 @@ static int is_lun_busy(struct scsi_cmnd
 static void cmd_get_tag(struct scsi_cmnd *cmd, int should_be_tagged)
 {
 	u8 lun = cmd->device->lun;
-	SETUP_HOSTDATA(cmd->device->host);
+	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.
@@ -316,18 +317,16 @@ static void cmd_get_tag(struct scsi_cmnd
 	    !cmd->device->tagged_supported) {
 		cmd->tag = TAG_NONE;
 		hostdata->busy[cmd->device->id] |= (1 << lun);
-		dprintk(NDEBUG_TAGS, "scsi%d: target %d lun %d now allocated by untagged "
-			   "command\n", H_NO(cmd), cmd->device->id, 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++;
-		dprintk(NDEBUG_TAGS, "scsi%d: using tag %d for target %d lun %d "
-			   "(now %d tags in use)\n",
-			   H_NO(cmd), cmd->tag, cmd->device->id,
-			   lun, 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);
 	}
 }
 
@@ -339,21 +338,22 @@ static void cmd_get_tag(struct scsi_cmnd
 static void cmd_free_tag(struct scsi_cmnd *cmd)
 {
 	u8 lun = cmd->device->lun;
-	SETUP_HOSTDATA(cmd->device->host);
+	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);
-		dprintk(NDEBUG_TAGS, "scsi%d: target %d lun %d untagged cmd finished\n",
-			   H_NO(cmd), cmd->device->id, lun);
+		dsprintk(NDEBUG_TAGS, instance, "target %d lun %d untagged cmd freed\n",
+		         scmd_id(cmd), lun);
 	} else if (cmd->tag >= MAX_TAGS) {
-		printk(KERN_NOTICE "scsi%d: trying to free bad tag %d!\n",
-		       H_NO(cmd), cmd->tag);
+		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--;
-		dprintk(NDEBUG_TAGS, "scsi%d: freed tag %d for target %d lun %d\n",
-			   H_NO(cmd), cmd->tag, cmd->device->id, lun);
+		dsprintk(NDEBUG_TAGS, instance, "freed tag %d for target %d lun %d\n",
+		         cmd->tag, scmd_id(cmd), lun);
 	}
 }
 
@@ -812,8 +812,7 @@ static int NCR5380_queue_command(struct
 	switch (cmd->cmnd[0]) {
 	case WRITE_6:
 	case WRITE_10:
-		printk(KERN_NOTICE "scsi%d: WRITE attempted with NO_WRITE debugging flag set\n",
-		       H_NO(cmd));
+		shost_printk(KERN_DEBUG, instance, "WRITE attempted with NDEBUG_NO_WRITE set\n");
 		cmd->result = (DID_ERROR << 16);
 		cmd->scsi_done(cmd);
 		return 0;
@@ -872,8 +871,8 @@ static int NCR5380_queue_command(struct
 	}
 	spin_unlock_irqrestore(&hostdata->lock, flags);
 
-	dprintk(NDEBUG_QUEUES, "scsi%d: command added to %s of queue\n", H_NO(cmd),
-		  (cmd->cmnd[0] == REQUEST_SENSE) ? "head" : "tail");
+	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);
@@ -1319,8 +1318,7 @@ static int NCR5380_select(struct Scsi_Ho
 	    (NCR5380_read(INITIATOR_COMMAND_REG) & ICR_ARBITRATION_LOST)) {
 		NCR5380_write(MODE_REG, MR_BASE);
 		NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
-		dprintk(NDEBUG_ARBITRATION, "scsi%d: lost arbitration, deasserting ICR_ASSERT_SEL\n",
-			   HOSTNO);
+		dsprintk(NDEBUG_ARBITRATION, instance, "arbitration lost, negating SEL\n");
 		spin_lock_irq(&hostdata->lock);
 		return -1;
 	}
@@ -2089,8 +2087,9 @@ static void NCR5380_information_transfer
 						LIST(cmd,hostdata->issue_queue);
 						SET_NEXT(cmd, hostdata->issue_queue);
 						hostdata->issue_queue = (struct scsi_cmnd *) cmd;
-						dprintk(NDEBUG_QUEUES, "scsi%d: REQUEST SENSE added to head of "
-							  "issue queue\n", H_NO(cmd));
+						dsprintk(NDEBUG_QUEUES, instance,
+						         "REQUEST SENSE cmd %p added to head of issue queue\n",
+						         cmd);
 					} else {
 						cmd->scsi_done(cmd);
 					}
@@ -2756,11 +2755,11 @@ static int NCR5380_bus_reset(struct scsi
 	 */
 
 	if (hostdata->issue_queue)
-		dprintk(NDEBUG_ABORT, "scsi%d: reset aborted issued command(s)\n", H_NO(cmd));
+		dsprintk(NDEBUG_ABORT, instance, "reset aborted issued command(s)\n");
 	if (hostdata->connected)
-		dprintk(NDEBUG_ABORT, "scsi%d: reset aborted a connected command\n", H_NO(cmd));
+		dsprintk(NDEBUG_ABORT, instance, "reset aborted a connected command\n");
 	if (hostdata->disconnected_queue)
-		dprintk(NDEBUG_ABORT, "scsi%d: reset aborted disconnected command(s)\n", H_NO(cmd));
+		dsprintk(NDEBUG_ABORT, instance, "reset aborted disconnected command(s)\n");
 
 	hostdata->issue_queue = NULL;
 	hostdata->connected = NULL;
Index: linux/drivers/scsi/NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/NCR5380.c	2015-11-18 19:34:12.000000000 +1100
+++ linux/drivers/scsi/NCR5380.c	2015-11-18 19:34:14.000000000 +1100
@@ -751,7 +751,7 @@ static int NCR5380_queue_command(struct
 	switch (cmd->cmnd[0]) {
 	case WRITE_6:
 	case WRITE_10:
-		printk("scsi%d : WRITE attempted with NO_WRITE debugging flag set\n", instance->host_no);
+		shost_printk(KERN_DEBUG, instance, "WRITE attempted with NDEBUG_NO_WRITE set\n");
 		cmd->result = (DID_ERROR << 16);
 		cmd->scsi_done(cmd);
 		return 0;
@@ -786,7 +786,8 @@ static int NCR5380_queue_command(struct
 	}
 	spin_unlock_irqrestore(&hostdata->lock, flags);
 
-	dprintk(NDEBUG_QUEUES, "scsi%d : command added to %s of queue\n", instance->host_no, (cmd->cmnd[0] == REQUEST_SENSE) ? "head" : "tail");
+	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);
@@ -1101,7 +1102,7 @@ static int NCR5380_select(struct Scsi_Ho
 	    (NCR5380_read(INITIATOR_COMMAND_REG) & ICR_ARBITRATION_LOST)) {
 		NCR5380_write(MODE_REG, MR_BASE);
 		NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
-		dprintk(NDEBUG_ARBITRATION, "scsi%d : lost arbitration, deasserting ICR_ASSERT_SEL\n", instance->host_no);
+		dsprintk(NDEBUG_ARBITRATION, instance, "arbitration lost, negating SEL\n");
 		spin_lock_irq(&hostdata->lock);
 		return -1;
 	}
@@ -1895,7 +1896,9 @@ static void NCR5380_information_transfer
 						cmd->host_scribble = (unsigned char *)
 						    hostdata->issue_queue;
 						hostdata->issue_queue = (struct scsi_cmnd *) cmd;
-						dprintk(NDEBUG_QUEUES, "scsi%d : REQUEST SENSE added to head of issue queue\n", instance->host_no);
+						dsprintk(NDEBUG_QUEUES, instance,
+						         "REQUEST SENSE cmd %p added to head of issue queue\n",
+						         cmd);
 					} else {
 						cmd->scsi_done(cmd);
 					}



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

* [PATCH 53/71] ncr5380: Use shost_priv helper
  2015-11-18  8:34 ` Finn Thain
@ 2015-11-18  8:35   ` Finn Thain
  -1 siblings, 0 replies; 268+ messages in thread
From: Finn Thain @ 2015-11-18  8:35 UTC (permalink / raw)
  To: James E.J. Bottomley, Michael Schmitz, linux-m68k, linux-scsi,
	linux-kernel

[-- Attachment #1: ncr5380-use-shost_priv --]
[-- Type: text/plain, Size: 6987 bytes --]

Make use of the shost_priv() helper. Remove HOSTDATA and SETUP_HOSTDATA
macros because they harm readability.

Signed-off-by: Finn Thain <fthain@telegraphics.com.au>

---
 drivers/scsi/NCR5380.c       |   23 ++++++++++-------------
 drivers/scsi/atari_NCR5380.c |   20 +++++++-------------
 2 files changed, 17 insertions(+), 26 deletions(-)

Index: linux/drivers/scsi/NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/NCR5380.c	2015-11-18 19:34:14.000000000 +1100
+++ linux/drivers/scsi/NCR5380.c	2015-11-18 19:34:15.000000000 +1100
@@ -475,7 +475,7 @@ static irqreturn_t __init probe_intr(int
 static int __init __maybe_unused NCR5380_probe_irq(struct Scsi_Host *instance,
 						int possible)
 {
-	struct NCR5380_hostdata *hostdata = (struct NCR5380_hostdata *) instance->hostdata;
+	struct NCR5380_hostdata *hostdata = shost_priv(instance);
 	unsigned long timeout;
 	int trying_irqs, i, mask;
 
@@ -598,9 +598,7 @@ static int __maybe_unused NCR5380_write_
 static int __maybe_unused NCR5380_show_info(struct seq_file *m,
 	struct Scsi_Host *instance)
 {
-	struct NCR5380_hostdata *hostdata;
-
-	hostdata = (struct NCR5380_hostdata *) instance->hostdata;
+	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);
@@ -626,8 +624,8 @@ static int __maybe_unused NCR5380_show_i
 
 static int NCR5380_init(struct Scsi_Host *instance, int flags)
 {
+	struct NCR5380_hostdata *hostdata = shost_priv(instance);
 	int i;
-	struct NCR5380_hostdata *hostdata = (struct NCR5380_hostdata *) instance->hostdata;
 
 	if(in_interrupt())
 		printk(KERN_ERR "NCR5380_init called with interrupts off!\n");
@@ -724,7 +722,7 @@ static int NCR5380_maybe_reset_bus(struc
 
 static void NCR5380_exit(struct Scsi_Host *instance)
 {
-	struct NCR5380_hostdata *hostdata = (struct NCR5380_hostdata *) instance->hostdata;
+	struct NCR5380_hostdata *hostdata = shost_priv(instance);
 
 	cancel_work_sync(&hostdata->main_task);
 	destroy_workqueue(hostdata->work_q);
@@ -1033,7 +1031,7 @@ static irqreturn_t NCR5380_intr(int irq,
  
 static int NCR5380_select(struct Scsi_Host *instance, struct scsi_cmnd *cmd)
 {
-	struct NCR5380_hostdata *hostdata = (struct NCR5380_hostdata *) instance->hostdata;
+	struct NCR5380_hostdata *hostdata = shost_priv(instance);
 	unsigned char tmp[3], phase;
 	unsigned char *data;
 	int len;
@@ -1518,7 +1516,7 @@ static int NCR5380_transfer_dma(struct S
 	unsigned char saved_data = 0, overrun = 0, residue;
 #endif
 
-	struct NCR5380_hostdata *hostdata = (struct NCR5380_hostdata *) instance->hostdata;
+	struct NCR5380_hostdata *hostdata = shost_priv(instance);
 
 	if ((tmp = (NCR5380_read(STATUS_REG) & PHASE_MASK)) != p) {
 		*phase = tmp;
@@ -1750,7 +1748,7 @@ static int NCR5380_transfer_dma(struct S
  */
 
 static void NCR5380_information_transfer(struct Scsi_Host *instance) {
-	struct NCR5380_hostdata *hostdata = (struct NCR5380_hostdata *)instance->hostdata;
+	struct NCR5380_hostdata *hostdata = shost_priv(instance);
 	unsigned char msgout = NOP;
 	int sink = 0;
 	int len;
@@ -2097,8 +2095,7 @@ static void NCR5380_information_transfer
  */
 
 static void NCR5380_reselect(struct Scsi_Host *instance) {
-	struct NCR5380_hostdata *hostdata = (struct NCR5380_hostdata *)
-	 instance->hostdata;
+	struct NCR5380_hostdata *hostdata = shost_priv(instance);
 	unsigned char target_mask;
 	unsigned char lun, phase;
 	int len;
@@ -2221,7 +2218,7 @@ static void NCR5380_reselect(struct Scsi
 
 #ifdef REAL_DMA
 static void NCR5380_dma_complete(NCR5380_instance * instance) {
-	struct NCR5380_hostdata *hostdata = (struct NCR5380_hostdata *) instance->hostdata;
+	struct NCR5380_hostdata *hostdata = shost_priv(instance);
 	int transferred;
 
 	/*
@@ -2275,7 +2272,7 @@ static void NCR5380_dma_complete(NCR5380
 static int NCR5380_abort(struct scsi_cmnd *cmd)
 {
 	struct Scsi_Host *instance = cmd->device->host;
-	struct NCR5380_hostdata *hostdata = (struct NCR5380_hostdata *) instance->hostdata;
+	struct NCR5380_hostdata *hostdata = shost_priv(instance);
 	struct scsi_cmnd *tmp, **prev;
 	unsigned long flags;
 
Index: linux/drivers/scsi/atari_NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/atari_NCR5380.c	2015-11-18 19:34:14.000000000 +1100
+++ linux/drivers/scsi/atari_NCR5380.c	2015-11-18 19:34:15.000000000 +1100
@@ -196,12 +196,6 @@
  * possible) function may be used.
  */
 
-/* Macros ease life... :-) */
-#define	SETUP_HOSTDATA(in)				\
-    struct NCR5380_hostdata *hostdata =			\
-	(struct NCR5380_hostdata *)(in)->hostdata
-#define	HOSTDATA(in) ((struct NCR5380_hostdata *)(in)->hostdata)
-
 #define	NEXT(cmd)		((struct scsi_cmnd *)(cmd)->host_scribble)
 #define	SET_NEXT(cmd,next)	((cmd)->host_scribble = (void *)(next))
 #define	NEXTADDR(cmd)		((struct scsi_cmnd **)&(cmd)->host_scribble)
@@ -684,8 +678,8 @@ static void prepare_info(struct Scsi_Hos
 
 static int __init NCR5380_init(struct Scsi_Host *instance, int flags)
 {
+	struct NCR5380_hostdata *hostdata = shost_priv(instance);
 	int i;
-	SETUP_HOSTDATA(instance);
 
 	hostdata->host = instance;
 	hostdata->id_mask = 1 << instance->this_id;
@@ -1035,7 +1029,7 @@ static void NCR5380_main(struct work_str
 
 static void NCR5380_dma_complete(struct Scsi_Host *instance)
 {
-	SETUP_HOSTDATA(instance);
+	struct NCR5380_hostdata *hostdata = shost_priv(instance);
 	int transferred;
 	unsigned char **data;
 	volatile int *count;
@@ -1245,7 +1239,7 @@ static irqreturn_t NCR5380_intr(int irq,
 
 static int NCR5380_select(struct Scsi_Host *instance, struct scsi_cmnd *cmd)
 {
-	SETUP_HOSTDATA(instance);
+	struct NCR5380_hostdata *hostdata = shost_priv(instance);
 	unsigned char tmp[3], phase;
 	unsigned char *data;
 	int len;
@@ -1751,7 +1745,7 @@ static int NCR5380_transfer_dma(struct S
 				unsigned char *phase, int *count,
 				unsigned char **data)
 {
-	SETUP_HOSTDATA(instance);
+	struct NCR5380_hostdata *hostdata = shost_priv(instance);
 	register int c = *count;
 	register unsigned char p = *phase;
 
@@ -1859,7 +1853,7 @@ static int NCR5380_transfer_dma(struct S
 
 static void NCR5380_information_transfer(struct Scsi_Host *instance)
 {
-	SETUP_HOSTDATA(instance);
+	struct NCR5380_hostdata *hostdata = shost_priv(instance);
 	unsigned char msgout = NOP;
 	int sink = 0;
 	int len;
@@ -2323,7 +2317,7 @@ static void NCR5380_information_transfer
 
 static void NCR5380_reselect(struct Scsi_Host *instance)
 {
-	SETUP_HOSTDATA(instance);
+	struct NCR5380_hostdata *hostdata = shost_priv(instance);
 	unsigned char target_mask;
 	unsigned char lun;
 #ifdef SUPPORT_TAGS
@@ -2530,7 +2524,7 @@ static
 int NCR5380_abort(struct scsi_cmnd *cmd)
 {
 	struct Scsi_Host *instance = cmd->device->host;
-	SETUP_HOSTDATA(instance);
+	struct NCR5380_hostdata *hostdata = shost_priv(instance);
 	struct scsi_cmnd *tmp, **prev;
 	unsigned long flags;
 



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

* [PATCH 53/71] ncr5380: Use shost_priv helper
@ 2015-11-18  8:35   ` Finn Thain
  0 siblings, 0 replies; 268+ messages in thread
From: Finn Thain @ 2015-11-18  8:35 UTC (permalink / raw)
  To: James E.J. Bottomley, Michael Schmitz, linux-m68k, linux-scsi,
	linux-kernel

[-- Attachment #1: ncr5380-use-shost_priv --]
[-- Type: text/plain, Size: 6985 bytes --]

Make use of the shost_priv() helper. Remove HOSTDATA and SETUP_HOSTDATA
macros because they harm readability.

Signed-off-by: Finn Thain <fthain@telegraphics.com.au>

---
 drivers/scsi/NCR5380.c       |   23 ++++++++++-------------
 drivers/scsi/atari_NCR5380.c |   20 +++++++-------------
 2 files changed, 17 insertions(+), 26 deletions(-)

Index: linux/drivers/scsi/NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/NCR5380.c	2015-11-18 19:34:14.000000000 +1100
+++ linux/drivers/scsi/NCR5380.c	2015-11-18 19:34:15.000000000 +1100
@@ -475,7 +475,7 @@ static irqreturn_t __init probe_intr(int
 static int __init __maybe_unused NCR5380_probe_irq(struct Scsi_Host *instance,
 						int possible)
 {
-	struct NCR5380_hostdata *hostdata = (struct NCR5380_hostdata *) instance->hostdata;
+	struct NCR5380_hostdata *hostdata = shost_priv(instance);
 	unsigned long timeout;
 	int trying_irqs, i, mask;
 
@@ -598,9 +598,7 @@ static int __maybe_unused NCR5380_write_
 static int __maybe_unused NCR5380_show_info(struct seq_file *m,
 	struct Scsi_Host *instance)
 {
-	struct NCR5380_hostdata *hostdata;
-
-	hostdata = (struct NCR5380_hostdata *) instance->hostdata;
+	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);
@@ -626,8 +624,8 @@ static int __maybe_unused NCR5380_show_i
 
 static int NCR5380_init(struct Scsi_Host *instance, int flags)
 {
+	struct NCR5380_hostdata *hostdata = shost_priv(instance);
 	int i;
-	struct NCR5380_hostdata *hostdata = (struct NCR5380_hostdata *) instance->hostdata;
 
 	if(in_interrupt())
 		printk(KERN_ERR "NCR5380_init called with interrupts off!\n");
@@ -724,7 +722,7 @@ static int NCR5380_maybe_reset_bus(struc
 
 static void NCR5380_exit(struct Scsi_Host *instance)
 {
-	struct NCR5380_hostdata *hostdata = (struct NCR5380_hostdata *) instance->hostdata;
+	struct NCR5380_hostdata *hostdata = shost_priv(instance);
 
 	cancel_work_sync(&hostdata->main_task);
 	destroy_workqueue(hostdata->work_q);
@@ -1033,7 +1031,7 @@ static irqreturn_t NCR5380_intr(int irq,
  
 static int NCR5380_select(struct Scsi_Host *instance, struct scsi_cmnd *cmd)
 {
-	struct NCR5380_hostdata *hostdata = (struct NCR5380_hostdata *) instance->hostdata;
+	struct NCR5380_hostdata *hostdata = shost_priv(instance);
 	unsigned char tmp[3], phase;
 	unsigned char *data;
 	int len;
@@ -1518,7 +1516,7 @@ static int NCR5380_transfer_dma(struct S
 	unsigned char saved_data = 0, overrun = 0, residue;
 #endif
 
-	struct NCR5380_hostdata *hostdata = (struct NCR5380_hostdata *) instance->hostdata;
+	struct NCR5380_hostdata *hostdata = shost_priv(instance);
 
 	if ((tmp = (NCR5380_read(STATUS_REG) & PHASE_MASK)) != p) {
 		*phase = tmp;
@@ -1750,7 +1748,7 @@ static int NCR5380_transfer_dma(struct S
  */
 
 static void NCR5380_information_transfer(struct Scsi_Host *instance) {
-	struct NCR5380_hostdata *hostdata = (struct NCR5380_hostdata *)instance->hostdata;
+	struct NCR5380_hostdata *hostdata = shost_priv(instance);
 	unsigned char msgout = NOP;
 	int sink = 0;
 	int len;
@@ -2097,8 +2095,7 @@ static void NCR5380_information_transfer
  */
 
 static void NCR5380_reselect(struct Scsi_Host *instance) {
-	struct NCR5380_hostdata *hostdata = (struct NCR5380_hostdata *)
-	 instance->hostdata;
+	struct NCR5380_hostdata *hostdata = shost_priv(instance);
 	unsigned char target_mask;
 	unsigned char lun, phase;
 	int len;
@@ -2221,7 +2218,7 @@ static void NCR5380_reselect(struct Scsi
 
 #ifdef REAL_DMA
 static void NCR5380_dma_complete(NCR5380_instance * instance) {
-	struct NCR5380_hostdata *hostdata = (struct NCR5380_hostdata *) instance->hostdata;
+	struct NCR5380_hostdata *hostdata = shost_priv(instance);
 	int transferred;
 
 	/*
@@ -2275,7 +2272,7 @@ static void NCR5380_dma_complete(NCR5380
 static int NCR5380_abort(struct scsi_cmnd *cmd)
 {
 	struct Scsi_Host *instance = cmd->device->host;
-	struct NCR5380_hostdata *hostdata = (struct NCR5380_hostdata *) instance->hostdata;
+	struct NCR5380_hostdata *hostdata = shost_priv(instance);
 	struct scsi_cmnd *tmp, **prev;
 	unsigned long flags;
 
Index: linux/drivers/scsi/atari_NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/atari_NCR5380.c	2015-11-18 19:34:14.000000000 +1100
+++ linux/drivers/scsi/atari_NCR5380.c	2015-11-18 19:34:15.000000000 +1100
@@ -196,12 +196,6 @@
  * possible) function may be used.
  */
 
-/* Macros ease life... :-) */
-#define	SETUP_HOSTDATA(in)				\
-    struct NCR5380_hostdata *hostdata =			\
-	(struct NCR5380_hostdata *)(in)->hostdata
-#define	HOSTDATA(in) ((struct NCR5380_hostdata *)(in)->hostdata)
-
 #define	NEXT(cmd)		((struct scsi_cmnd *)(cmd)->host_scribble)
 #define	SET_NEXT(cmd,next)	((cmd)->host_scribble = (void *)(next))
 #define	NEXTADDR(cmd)		((struct scsi_cmnd **)&(cmd)->host_scribble)
@@ -684,8 +678,8 @@ static void prepare_info(struct Scsi_Hos
 
 static int __init NCR5380_init(struct Scsi_Host *instance, int flags)
 {
+	struct NCR5380_hostdata *hostdata = shost_priv(instance);
 	int i;
-	SETUP_HOSTDATA(instance);
 
 	hostdata->host = instance;
 	hostdata->id_mask = 1 << instance->this_id;
@@ -1035,7 +1029,7 @@ static void NCR5380_main(struct work_str
 
 static void NCR5380_dma_complete(struct Scsi_Host *instance)
 {
-	SETUP_HOSTDATA(instance);
+	struct NCR5380_hostdata *hostdata = shost_priv(instance);
 	int transferred;
 	unsigned char **data;
 	volatile int *count;
@@ -1245,7 +1239,7 @@ static irqreturn_t NCR5380_intr(int irq,
 
 static int NCR5380_select(struct Scsi_Host *instance, struct scsi_cmnd *cmd)
 {
-	SETUP_HOSTDATA(instance);
+	struct NCR5380_hostdata *hostdata = shost_priv(instance);
 	unsigned char tmp[3], phase;
 	unsigned char *data;
 	int len;
@@ -1751,7 +1745,7 @@ static int NCR5380_transfer_dma(struct S
 				unsigned char *phase, int *count,
 				unsigned char **data)
 {
-	SETUP_HOSTDATA(instance);
+	struct NCR5380_hostdata *hostdata = shost_priv(instance);
 	register int c = *count;
 	register unsigned char p = *phase;
 
@@ -1859,7 +1853,7 @@ static int NCR5380_transfer_dma(struct S
 
 static void NCR5380_information_transfer(struct Scsi_Host *instance)
 {
-	SETUP_HOSTDATA(instance);
+	struct NCR5380_hostdata *hostdata = shost_priv(instance);
 	unsigned char msgout = NOP;
 	int sink = 0;
 	int len;
@@ -2323,7 +2317,7 @@ static void NCR5380_information_transfer
 
 static void NCR5380_reselect(struct Scsi_Host *instance)
 {
-	SETUP_HOSTDATA(instance);
+	struct NCR5380_hostdata *hostdata = shost_priv(instance);
 	unsigned char target_mask;
 	unsigned char lun;
 #ifdef SUPPORT_TAGS
@@ -2530,7 +2524,7 @@ static
 int NCR5380_abort(struct scsi_cmnd *cmd)
 {
 	struct Scsi_Host *instance = cmd->device->host;
-	SETUP_HOSTDATA(instance);
+	struct NCR5380_hostdata *hostdata = shost_priv(instance);
 	struct scsi_cmnd *tmp, **prev;
 	unsigned long flags;
 

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

* [PATCH 54/71] ncr5380: Use dsprintk() for queue debugging
  2015-11-18  8:34 ` Finn Thain
@ 2015-11-18  8:35   ` Finn Thain
  -1 siblings, 0 replies; 268+ messages in thread
From: Finn Thain @ 2015-11-18  8:35 UTC (permalink / raw)
  To: James E.J. Bottomley, Michael Schmitz, linux-m68k, linux-scsi,
	linux-kernel

[-- Attachment #1: ncr5380-use-dsprintk-for-queue-debugging --]
[-- Type: text/plain, Size: 9834 bytes --]

Print the command pointers in the log messages for debugging queue data
structures. The LIST and REMOVE macros can then be removed.

Signed-off-by: Finn Thain <fthain@telegraphics.com.au>

---
 drivers/scsi/NCR5380.c       |   36 ++++++++++++++++++++++++------------
 drivers/scsi/atari_NCR5380.c |   43 +++++++++++++++++++++++--------------------
 2 files changed, 47 insertions(+), 32 deletions(-)

Index: linux/drivers/scsi/atari_NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/atari_NCR5380.c	2015-11-18 19:34:15.000000000 +1100
+++ linux/drivers/scsi/atari_NCR5380.c	2015-11-18 19:34:16.000000000 +1100
@@ -933,10 +933,8 @@ static void NCR5380_main(struct work_str
 			     prev = NULL; tmp; prev = tmp, tmp = NEXT(tmp)) {
 				u8 lun = tmp->device->lun;
 
-				dprintk(NDEBUG_LISTS,
-				        "MAIN tmp=%p target=%d busy=%d lun=%d\n",
-				        tmp, scmd_id(tmp), hostdata->busy[scmd_id(tmp)],
-				        lun);
+				dsprintk(NDEBUG_QUEUES, instance, "main: tmp=%p target=%d busy=%d lun=%d\n",
+				         tmp, scmd_id(tmp), hostdata->busy[scmd_id(tmp)], lun);
 				/*  When we find one, remove it from the issue queue. */
 				if (
 #ifdef SUPPORT_TAGS
@@ -953,6 +951,10 @@ static void NCR5380_main(struct work_str
 						hostdata->issue_queue = NEXT(tmp);
 					}
 					SET_NEXT(tmp, NULL);
+					dsprintk(NDEBUG_MAIN | NDEBUG_QUEUES,
+					         instance, "main: removed %p from issue queue %p\n",
+					         tmp, prev);
+
 					hostdata->retain_dma_intr++;
 
 					/*
@@ -961,9 +963,6 @@ static void NCR5380_main(struct work_str
 					 * On failure, we must add the command back to the
 					 *   issue queue so we can keep trying.
 					 */
-					dprintk(NDEBUG_MAIN, "scsi%d: main(): command for target %d "
-						    "lun %d removed from issue_queue\n",
-						    HOSTNO, tmp->device->id, lun);
 					/*
 					 * REQUEST SENSE commands are issued without tagged
 					 * queueing, even on SCSI-II devices because the
@@ -986,13 +985,14 @@ static void NCR5380_main(struct work_str
 						LIST(tmp, hostdata->issue_queue);
 						SET_NEXT(tmp, hostdata->issue_queue);
 						hostdata->issue_queue = tmp;
+						dsprintk(NDEBUG_MAIN | NDEBUG_QUEUES,
+						         instance, "main: select() failed, %p returned to issue queue\n",
+						         tmp);
 #ifdef SUPPORT_TAGS
 						cmd_free_tag(tmp);
 #endif
 						hostdata->retain_dma_intr--;
 						done = 0;
-						dprintk(NDEBUG_MAIN, "scsi%d: main(): select() failed, "
-							    "returned to issue_queue\n", HOSTNO);
 					}
 					if (hostdata->connected)
 						break;
@@ -2026,8 +2026,9 @@ static void NCR5380_information_transfer
 				case COMMAND_COMPLETE:
 					/* Accept message by clearing ACK */
 					NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
-					dprintk(NDEBUG_QUEUES, "scsi%d: command for target %d, lun %llu "
-						  "completed\n", HOSTNO, cmd->device->id, cmd->device->lun);
+					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
@@ -2076,13 +2077,11 @@ static void NCR5380_information_transfer
 					    (status_byte(cmd->SCp.Status) == CHECK_CONDITION)) {
 						scsi_eh_prep_cmnd(cmd, &hostdata->ses, NULL, 0, ~0);
 
-						dprintk(NDEBUG_AUTOSENSE, "scsi%d: performing request sense\n", HOSTNO);
-
 						LIST(cmd,hostdata->issue_queue);
 						SET_NEXT(cmd, hostdata->issue_queue);
 						hostdata->issue_queue = (struct scsi_cmnd *) cmd;
-						dsprintk(NDEBUG_QUEUES, instance,
-						         "REQUEST SENSE cmd %p added to head of issue queue\n",
+						dsprintk(NDEBUG_AUTOSENSE | NDEBUG_QUEUES,
+						         instance, "REQUEST SENSE cmd %p added to head of issue queue\n",
 						         cmd);
 					} else {
 						cmd->scsi_done(cmd);
@@ -2133,10 +2132,10 @@ static void NCR5380_information_transfer
 					SET_NEXT(cmd, hostdata->disconnected_queue);
 					hostdata->connected = NULL;
 					hostdata->disconnected_queue = cmd;
-					dprintk(NDEBUG_QUEUES, "scsi%d: command for target %d lun %llu was "
-						  "moved from connected to the "
-						  "disconnected_queue\n", HOSTNO,
-						  cmd->device->id, cmd->device->lun);
+					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.
@@ -2436,7 +2435,11 @@ static void NCR5380_reselect(struct Scsi
 		}
 	}
 
-	if (!tmp) {
+	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);
Index: linux/drivers/scsi/NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/NCR5380.c	2015-11-18 19:34:15.000000000 +1100
+++ linux/drivers/scsi/NCR5380.c	2015-11-18 19:34:16.000000000 +1100
@@ -824,8 +824,9 @@ static void NCR5380_main(struct work_str
 			 */
 			for (tmp = (struct scsi_cmnd *) hostdata->issue_queue, prev = NULL; tmp; prev = tmp, tmp = (struct scsi_cmnd *) tmp->host_scribble)
 			{
-				if (prev != tmp)
-				    dprintk(NDEBUG_LISTS, "MAIN tmp=%p   target=%d   busy=%d lun=%llu\n", tmp, tmp->device->id, hostdata->busy[tmp->device->id], tmp->device->lun);
+				dsprintk(NDEBUG_QUEUES, instance, "main: tmp=%p target=%d busy=%d lun=%llu\n",
+				         tmp, scmd_id(tmp), hostdata->busy[scmd_id(tmp)],
+				         tmp->device->lun);
 				/*  When we find one, remove it from the issue queue. */
 				if (!(hostdata->busy[tmp->device->id] &
 				      (1 << (u8)(tmp->device->lun & 0xff)))) {
@@ -837,6 +838,9 @@ static void NCR5380_main(struct work_str
 						hostdata->issue_queue = (struct scsi_cmnd *) tmp->host_scribble;
 					}
 					tmp->host_scribble = NULL;
+					dsprintk(NDEBUG_MAIN | NDEBUG_QUEUES,
+					         instance, "main: removed %p from issue queue %p\n",
+					         tmp, prev);
 
 					/* 
 					 * Attempt to establish an I_T_L nexus here. 
@@ -844,8 +848,6 @@ static void NCR5380_main(struct work_str
 					 * On failure, we must add the command back to the
 					 *   issue queue so we can keep trying. 
 					 */
-					dprintk(NDEBUG_MAIN|NDEBUG_QUEUES, "scsi%d : main() : command for target %d lun %llu removed from issue_queue\n", instance->host_no, tmp->device->id, tmp->device->lun);
-	
 					/*
 					 * REQUEST SENSE commands are issued without tagged
 					 * queueing, even on SCSI-II devices because the
@@ -860,8 +862,10 @@ static void NCR5380_main(struct work_str
 						LIST(tmp, hostdata->issue_queue);
 						tmp->host_scribble = (unsigned char *) hostdata->issue_queue;
 						hostdata->issue_queue = tmp;
+						dsprintk(NDEBUG_MAIN | NDEBUG_QUEUES,
+						         instance, "main: select() failed, %p returned to issue queue\n",
+						         tmp);
 						done = 0;
-						dprintk(NDEBUG_MAIN|NDEBUG_QUEUES, "scsi%d : main(): select() failed, returned to issue_queue\n", instance->host_no);
 					}
 					if (hostdata->connected)
 						break;
@@ -1854,8 +1858,11 @@ static void NCR5380_information_transfer
 					/* Accept message by clearing ACK */
 					sink = 1;
 					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;
-					dprintk(NDEBUG_QUEUES, "scsi%d : command for target %d, lun %llu completed\n", instance->host_no, cmd->device->id, cmd->device->lun);
 					hostdata->busy[cmd->device->id] &= ~(1 << (cmd->device->lun & 0xFF));
 
 					/* 
@@ -1888,14 +1895,12 @@ static void NCR5380_information_transfer
 					if ((cmd->cmnd[0] != REQUEST_SENSE) && (status_byte(cmd->SCp.Status) == CHECK_CONDITION)) {
 						scsi_eh_prep_cmnd(cmd, &hostdata->ses, NULL, 0, ~0);
 
-						dprintk(NDEBUG_AUTOSENSE, "scsi%d : performing request sense\n", instance->host_no);
-
 						LIST(cmd, hostdata->issue_queue);
 						cmd->host_scribble = (unsigned char *)
 						    hostdata->issue_queue;
 						hostdata->issue_queue = (struct scsi_cmnd *) cmd;
-						dsprintk(NDEBUG_QUEUES, instance,
-						         "REQUEST SENSE cmd %p added to head of issue queue\n",
+						dsprintk(NDEBUG_AUTOSENSE | NDEBUG_QUEUES,
+						         instance, "REQUEST SENSE cmd %p added to head of issue queue\n",
 						         cmd);
 					} else {
 						cmd->scsi_done(cmd);
@@ -1932,7 +1937,10 @@ static void NCR5380_information_transfer
 						    hostdata->disconnected_queue;
 						hostdata->connected = NULL;
 						hostdata->disconnected_queue = cmd;
-						dprintk(NDEBUG_QUEUES, "scsi%d : command for target %d lun %llu was moved from connected to" "  the disconnected_queue\n", instance->host_no, cmd->device->id, cmd->device->lun);
+						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.
@@ -2185,7 +2193,11 @@ static void NCR5380_reselect(struct Scsi
 			break;
 		}
 	}
-	if (!tmp) {
+
+	if (tmp) {
+		dsprintk(NDEBUG_RESELECTION | NDEBUG_QUEUES, instance,
+		         "reselect: removed %p from disconnected queue\n", tmp);
+	} else {
 		shost_printk(KERN_ERR, instance, "target bitmask 0x%02x lun %d not in disconnected queue.\n",
 		             target_mask, lun);
 		/*



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

* [PATCH 54/71] ncr5380: Use dsprintk() for queue debugging
@ 2015-11-18  8:35   ` Finn Thain
  0 siblings, 0 replies; 268+ messages in thread
From: Finn Thain @ 2015-11-18  8:35 UTC (permalink / raw)
  To: James E.J. Bottomley, Michael Schmitz, linux-m68k, linux-scsi,
	linux-kernel

[-- Attachment #1: ncr5380-use-dsprintk-for-queue-debugging --]
[-- Type: text/plain, Size: 9832 bytes --]

Print the command pointers in the log messages for debugging queue data
structures. The LIST and REMOVE macros can then be removed.

Signed-off-by: Finn Thain <fthain@telegraphics.com.au>

---
 drivers/scsi/NCR5380.c       |   36 ++++++++++++++++++++++++------------
 drivers/scsi/atari_NCR5380.c |   43 +++++++++++++++++++++++--------------------
 2 files changed, 47 insertions(+), 32 deletions(-)

Index: linux/drivers/scsi/atari_NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/atari_NCR5380.c	2015-11-18 19:34:15.000000000 +1100
+++ linux/drivers/scsi/atari_NCR5380.c	2015-11-18 19:34:16.000000000 +1100
@@ -933,10 +933,8 @@ static void NCR5380_main(struct work_str
 			     prev = NULL; tmp; prev = tmp, tmp = NEXT(tmp)) {
 				u8 lun = tmp->device->lun;
 
-				dprintk(NDEBUG_LISTS,
-				        "MAIN tmp=%p target=%d busy=%d lun=%d\n",
-				        tmp, scmd_id(tmp), hostdata->busy[scmd_id(tmp)],
-				        lun);
+				dsprintk(NDEBUG_QUEUES, instance, "main: tmp=%p target=%d busy=%d lun=%d\n",
+				         tmp, scmd_id(tmp), hostdata->busy[scmd_id(tmp)], lun);
 				/*  When we find one, remove it from the issue queue. */
 				if (
 #ifdef SUPPORT_TAGS
@@ -953,6 +951,10 @@ static void NCR5380_main(struct work_str
 						hostdata->issue_queue = NEXT(tmp);
 					}
 					SET_NEXT(tmp, NULL);
+					dsprintk(NDEBUG_MAIN | NDEBUG_QUEUES,
+					         instance, "main: removed %p from issue queue %p\n",
+					         tmp, prev);
+
 					hostdata->retain_dma_intr++;
 
 					/*
@@ -961,9 +963,6 @@ static void NCR5380_main(struct work_str
 					 * On failure, we must add the command back to the
 					 *   issue queue so we can keep trying.
 					 */
-					dprintk(NDEBUG_MAIN, "scsi%d: main(): command for target %d "
-						    "lun %d removed from issue_queue\n",
-						    HOSTNO, tmp->device->id, lun);
 					/*
 					 * REQUEST SENSE commands are issued without tagged
 					 * queueing, even on SCSI-II devices because the
@@ -986,13 +985,14 @@ static void NCR5380_main(struct work_str
 						LIST(tmp, hostdata->issue_queue);
 						SET_NEXT(tmp, hostdata->issue_queue);
 						hostdata->issue_queue = tmp;
+						dsprintk(NDEBUG_MAIN | NDEBUG_QUEUES,
+						         instance, "main: select() failed, %p returned to issue queue\n",
+						         tmp);
 #ifdef SUPPORT_TAGS
 						cmd_free_tag(tmp);
 #endif
 						hostdata->retain_dma_intr--;
 						done = 0;
-						dprintk(NDEBUG_MAIN, "scsi%d: main(): select() failed, "
-							    "returned to issue_queue\n", HOSTNO);
 					}
 					if (hostdata->connected)
 						break;
@@ -2026,8 +2026,9 @@ static void NCR5380_information_transfer
 				case COMMAND_COMPLETE:
 					/* Accept message by clearing ACK */
 					NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
-					dprintk(NDEBUG_QUEUES, "scsi%d: command for target %d, lun %llu "
-						  "completed\n", HOSTNO, cmd->device->id, cmd->device->lun);
+					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
@@ -2076,13 +2077,11 @@ static void NCR5380_information_transfer
 					    (status_byte(cmd->SCp.Status) == CHECK_CONDITION)) {
 						scsi_eh_prep_cmnd(cmd, &hostdata->ses, NULL, 0, ~0);
 
-						dprintk(NDEBUG_AUTOSENSE, "scsi%d: performing request sense\n", HOSTNO);
-
 						LIST(cmd,hostdata->issue_queue);
 						SET_NEXT(cmd, hostdata->issue_queue);
 						hostdata->issue_queue = (struct scsi_cmnd *) cmd;
-						dsprintk(NDEBUG_QUEUES, instance,
-						         "REQUEST SENSE cmd %p added to head of issue queue\n",
+						dsprintk(NDEBUG_AUTOSENSE | NDEBUG_QUEUES,
+						         instance, "REQUEST SENSE cmd %p added to head of issue queue\n",
 						         cmd);
 					} else {
 						cmd->scsi_done(cmd);
@@ -2133,10 +2132,10 @@ static void NCR5380_information_transfer
 					SET_NEXT(cmd, hostdata->disconnected_queue);
 					hostdata->connected = NULL;
 					hostdata->disconnected_queue = cmd;
-					dprintk(NDEBUG_QUEUES, "scsi%d: command for target %d lun %llu was "
-						  "moved from connected to the "
-						  "disconnected_queue\n", HOSTNO,
-						  cmd->device->id, cmd->device->lun);
+					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.
@@ -2436,7 +2435,11 @@ static void NCR5380_reselect(struct Scsi
 		}
 	}
 
-	if (!tmp) {
+	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);
Index: linux/drivers/scsi/NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/NCR5380.c	2015-11-18 19:34:15.000000000 +1100
+++ linux/drivers/scsi/NCR5380.c	2015-11-18 19:34:16.000000000 +1100
@@ -824,8 +824,9 @@ static void NCR5380_main(struct work_str
 			 */
 			for (tmp = (struct scsi_cmnd *) hostdata->issue_queue, prev = NULL; tmp; prev = tmp, tmp = (struct scsi_cmnd *) tmp->host_scribble)
 			{
-				if (prev != tmp)
-				    dprintk(NDEBUG_LISTS, "MAIN tmp=%p   target=%d   busy=%d lun=%llu\n", tmp, tmp->device->id, hostdata->busy[tmp->device->id], tmp->device->lun);
+				dsprintk(NDEBUG_QUEUES, instance, "main: tmp=%p target=%d busy=%d lun=%llu\n",
+				         tmp, scmd_id(tmp), hostdata->busy[scmd_id(tmp)],
+				         tmp->device->lun);
 				/*  When we find one, remove it from the issue queue. */
 				if (!(hostdata->busy[tmp->device->id] &
 				      (1 << (u8)(tmp->device->lun & 0xff)))) {
@@ -837,6 +838,9 @@ static void NCR5380_main(struct work_str
 						hostdata->issue_queue = (struct scsi_cmnd *) tmp->host_scribble;
 					}
 					tmp->host_scribble = NULL;
+					dsprintk(NDEBUG_MAIN | NDEBUG_QUEUES,
+					         instance, "main: removed %p from issue queue %p\n",
+					         tmp, prev);
 
 					/* 
 					 * Attempt to establish an I_T_L nexus here. 
@@ -844,8 +848,6 @@ static void NCR5380_main(struct work_str
 					 * On failure, we must add the command back to the
 					 *   issue queue so we can keep trying. 
 					 */
-					dprintk(NDEBUG_MAIN|NDEBUG_QUEUES, "scsi%d : main() : command for target %d lun %llu removed from issue_queue\n", instance->host_no, tmp->device->id, tmp->device->lun);
-	
 					/*
 					 * REQUEST SENSE commands are issued without tagged
 					 * queueing, even on SCSI-II devices because the
@@ -860,8 +862,10 @@ static void NCR5380_main(struct work_str
 						LIST(tmp, hostdata->issue_queue);
 						tmp->host_scribble = (unsigned char *) hostdata->issue_queue;
 						hostdata->issue_queue = tmp;
+						dsprintk(NDEBUG_MAIN | NDEBUG_QUEUES,
+						         instance, "main: select() failed, %p returned to issue queue\n",
+						         tmp);
 						done = 0;
-						dprintk(NDEBUG_MAIN|NDEBUG_QUEUES, "scsi%d : main(): select() failed, returned to issue_queue\n", instance->host_no);
 					}
 					if (hostdata->connected)
 						break;
@@ -1854,8 +1858,11 @@ static void NCR5380_information_transfer
 					/* Accept message by clearing ACK */
 					sink = 1;
 					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;
-					dprintk(NDEBUG_QUEUES, "scsi%d : command for target %d, lun %llu completed\n", instance->host_no, cmd->device->id, cmd->device->lun);
 					hostdata->busy[cmd->device->id] &= ~(1 << (cmd->device->lun & 0xFF));
 
 					/* 
@@ -1888,14 +1895,12 @@ static void NCR5380_information_transfer
 					if ((cmd->cmnd[0] != REQUEST_SENSE) && (status_byte(cmd->SCp.Status) == CHECK_CONDITION)) {
 						scsi_eh_prep_cmnd(cmd, &hostdata->ses, NULL, 0, ~0);
 
-						dprintk(NDEBUG_AUTOSENSE, "scsi%d : performing request sense\n", instance->host_no);
-
 						LIST(cmd, hostdata->issue_queue);
 						cmd->host_scribble = (unsigned char *)
 						    hostdata->issue_queue;
 						hostdata->issue_queue = (struct scsi_cmnd *) cmd;
-						dsprintk(NDEBUG_QUEUES, instance,
-						         "REQUEST SENSE cmd %p added to head of issue queue\n",
+						dsprintk(NDEBUG_AUTOSENSE | NDEBUG_QUEUES,
+						         instance, "REQUEST SENSE cmd %p added to head of issue queue\n",
 						         cmd);
 					} else {
 						cmd->scsi_done(cmd);
@@ -1932,7 +1937,10 @@ static void NCR5380_information_transfer
 						    hostdata->disconnected_queue;
 						hostdata->connected = NULL;
 						hostdata->disconnected_queue = cmd;
-						dprintk(NDEBUG_QUEUES, "scsi%d : command for target %d lun %llu was moved from connected to" "  the disconnected_queue\n", instance->host_no, cmd->device->id, cmd->device->lun);
+						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.
@@ -2185,7 +2193,11 @@ static void NCR5380_reselect(struct Scsi
 			break;
 		}
 	}
-	if (!tmp) {
+
+	if (tmp) {
+		dsprintk(NDEBUG_RESELECTION | NDEBUG_QUEUES, instance,
+		         "reselect: removed %p from disconnected queue\n", tmp);
+	} else {
 		shost_printk(KERN_ERR, instance, "target bitmask 0x%02x lun %d not in disconnected queue.\n",
 		             target_mask, lun);
 		/*

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

* [PATCH 55/71] ncr5380: Remove LIST and REMOVE macros
  2015-11-18  8:34 ` Finn Thain
@ 2015-11-18  8:35   ` Finn Thain
  -1 siblings, 0 replies; 268+ messages in thread
From: Finn Thain @ 2015-11-18  8:35 UTC (permalink / raw)
  To: James E.J. Bottomley, Michael Schmitz, linux-m68k, linux-scsi,
	linux-kernel

[-- Attachment #1: ncr5380-remove-LIST-and-REMOVE-macros --]
[-- Type: text/plain, Size: 8550 bytes --]

Printing command pointers can be useful when debugging queues. Other than
that, the LIST and REMOVE macros are just clutter. These macros are
redundant now that NDEBUG_QUEUES causes pointers to be printed, so remove
them.

Signed-off-by: Finn Thain <fthain@telegraphics.com.au>

---
 drivers/scsi/NCR5380.c       |   19 -------------------
 drivers/scsi/atari_NCR5380.c |   32 --------------------------------
 2 files changed, 51 deletions(-)

Index: linux/drivers/scsi/NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/NCR5380.c	2015-11-18 19:34:16.000000000 +1100
+++ linux/drivers/scsi/NCR5380.c	2015-11-18 19:34:18.000000000 +1100
@@ -80,14 +80,6 @@
  *      tagged queueing)
  */
 
-#if (NDEBUG & NDEBUG_LISTS)
-#define LIST(x,y) {printk("LINE:%d   Adding %p to %p\n", __LINE__, (void*)(x), (void*)(y)); if ((x)==(y)) udelay(5); }
-#define REMOVE(w,x,y,z) {printk("LINE:%d   Removing: %p->%p  %p->%p \n", __LINE__, (void*)(w), (void*)(x), (void*)(y), (void*)(z)); if ((x)==(y)) udelay(5); }
-#else
-#define LIST(x,y)
-#define REMOVE(w,x,y,z)
-#endif
-
 #ifndef notyet
 #undef REAL_DMA
 #endif
@@ -774,12 +766,10 @@ static int NCR5380_queue_command(struct
 	 */
 
 	if (!(hostdata->issue_queue) || (cmd->cmnd[0] == REQUEST_SENSE)) {
-		LIST(cmd, hostdata->issue_queue);
 		cmd->host_scribble = (unsigned char *) hostdata->issue_queue;
 		hostdata->issue_queue = cmd;
 	} else {
 		for (tmp = (struct scsi_cmnd *) hostdata->issue_queue; tmp->host_scribble; tmp = (struct scsi_cmnd *) tmp->host_scribble);
-		LIST(cmd, tmp);
 		tmp->host_scribble = (unsigned char *) cmd;
 	}
 	spin_unlock_irqrestore(&hostdata->lock, flags);
@@ -831,10 +821,8 @@ static void NCR5380_main(struct work_str
 				if (!(hostdata->busy[tmp->device->id] &
 				      (1 << (u8)(tmp->device->lun & 0xff)))) {
 					if (prev) {
-						REMOVE(prev, prev->host_scribble, tmp, tmp->host_scribble);
 						prev->host_scribble = tmp->host_scribble;
 					} else {
-						REMOVE(-1, hostdata->issue_queue, tmp, tmp->host_scribble);
 						hostdata->issue_queue = (struct scsi_cmnd *) tmp->host_scribble;
 					}
 					tmp->host_scribble = NULL;
@@ -859,7 +847,6 @@ static void NCR5380_main(struct work_str
 						/* OK or bad target */
 					} else {
 						/* Need to retry */
-						LIST(tmp, hostdata->issue_queue);
 						tmp->host_scribble = (unsigned char *) hostdata->issue_queue;
 						hostdata->issue_queue = tmp;
 						dsprintk(NDEBUG_MAIN | NDEBUG_QUEUES,
@@ -1895,7 +1882,6 @@ static void NCR5380_information_transfer
 					if ((cmd->cmnd[0] != REQUEST_SENSE) && (status_byte(cmd->SCp.Status) == CHECK_CONDITION)) {
 						scsi_eh_prep_cmnd(cmd, &hostdata->ses, NULL, 0, ~0);
 
-						LIST(cmd, hostdata->issue_queue);
 						cmd->host_scribble = (unsigned char *)
 						    hostdata->issue_queue;
 						hostdata->issue_queue = (struct scsi_cmnd *) cmd;
@@ -1932,7 +1918,6 @@ static void NCR5380_information_transfer
 				case DISCONNECT:{
 						/* Accept message by clearing ACK */
 						NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
-						LIST(cmd, hostdata->disconnected_queue);
 						cmd->host_scribble = (unsigned char *)
 						    hostdata->disconnected_queue;
 						hostdata->connected = NULL;
@@ -2182,10 +2167,8 @@ static void NCR5380_reselect(struct Scsi
 	     tmp; prev = tmp, tmp = (struct scsi_cmnd *) tmp->host_scribble) {
 		if ((target_mask == (1 << tmp->device->id)) && (lun == (u8)tmp->device->lun)) {
 			if (prev) {
-				REMOVE(prev, prev->host_scribble, tmp, tmp->host_scribble);
 				prev->host_scribble = tmp->host_scribble;
 			} else {
-				REMOVE(-1, hostdata->disconnected_queue, tmp, tmp->host_scribble);
 				hostdata->disconnected_queue =
 					(struct scsi_cmnd *) tmp->host_scribble;
 			}
@@ -2336,7 +2319,6 @@ static int NCR5380_abort(struct scsi_cmn
 	dprintk(NDEBUG_ABORT, "scsi%d : abort going into loop.\n", instance->host_no);
 	for (prev = (struct scsi_cmnd **) &(hostdata->issue_queue), tmp = (struct scsi_cmnd *) hostdata->issue_queue; tmp; prev = (struct scsi_cmnd **) &(tmp->host_scribble), tmp = (struct scsi_cmnd *) tmp->host_scribble)
 		if (cmd == tmp) {
-			REMOVE(5, *prev, tmp, tmp->host_scribble);
 			(*prev) = (struct scsi_cmnd *) tmp->host_scribble;
 			tmp->host_scribble = NULL;
 			spin_unlock_irqrestore(&hostdata->lock, flags);
@@ -2406,7 +2388,6 @@ static int NCR5380_abort(struct scsi_cmn
 
 			for (prev = (struct scsi_cmnd **) &(hostdata->disconnected_queue), tmp = (struct scsi_cmnd *) hostdata->disconnected_queue; tmp; prev = (struct scsi_cmnd **) &(tmp->host_scribble), tmp = (struct scsi_cmnd *) tmp->host_scribble)
 				if (cmd == tmp) {
-					REMOVE(5, *prev, tmp, tmp->host_scribble);
 					*prev = (struct scsi_cmnd *) tmp->host_scribble;
 					tmp->host_scribble = NULL;
 					spin_unlock_irqrestore(&hostdata->lock, flags);
Index: linux/drivers/scsi/atari_NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/atari_NCR5380.c	2015-11-18 19:34:16.000000000 +1100
+++ linux/drivers/scsi/atari_NCR5380.c	2015-11-18 19:34:18.000000000 +1100
@@ -68,27 +68,6 @@
 
 /* Adapted for the sun3 by Sam Creasey. */
 
-#if (NDEBUG & NDEBUG_LISTS)
-#define LIST(x, y)						\
-	do {							\
-		printk("LINE:%d   Adding %p to %p\n",		\
-		       __LINE__, (void*)(x), (void*)(y));	\
-		if ((x) == (y))					\
-			udelay(5);				\
-	} while (0)
-#define REMOVE(w, x, y, z)					\
-	do {							\
-		printk("LINE:%d   Removing: %p->%p  %p->%p \n",	\
-		       __LINE__, (void*)(w), (void*)(x),	\
-		       (void*)(y), (void*)(z));			\
-		if ((x) == (y))					\
-			udelay(5);				\
-	} while (0)
-#else
-#define LIST(x,y)
-#define REMOVE(w,x,y,z)
-#endif
-
 /*
  * Design
  *
@@ -853,14 +832,12 @@ static int NCR5380_queue_command(struct
 	 */
 
 	if (!(hostdata->issue_queue) || (cmd->cmnd[0] == REQUEST_SENSE)) {
-		LIST(cmd, hostdata->issue_queue);
 		SET_NEXT(cmd, hostdata->issue_queue);
 		hostdata->issue_queue = cmd;
 	} else {
 		for (tmp = (struct scsi_cmnd *)hostdata->issue_queue;
 		     NEXT(tmp); tmp = NEXT(tmp))
 			;
-		LIST(cmd, tmp);
 		SET_NEXT(tmp, cmd);
 	}
 	spin_unlock_irqrestore(&hostdata->lock, flags);
@@ -944,10 +921,8 @@ static void NCR5380_main(struct work_str
 #endif
 				    ) {
 					if (prev) {
-						REMOVE(prev, NEXT(prev), tmp, NEXT(tmp));
 						SET_NEXT(prev, NEXT(tmp));
 					} else {
-						REMOVE(-1, hostdata->issue_queue, tmp, NEXT(tmp));
 						hostdata->issue_queue = NEXT(tmp);
 					}
 					SET_NEXT(tmp, NULL);
@@ -982,7 +957,6 @@ static void NCR5380_main(struct work_str
 						maybe_release_dma_irq(instance);
 					} else {
 						/* Need to retry */
-						LIST(tmp, hostdata->issue_queue);
 						SET_NEXT(tmp, hostdata->issue_queue);
 						hostdata->issue_queue = tmp;
 						dsprintk(NDEBUG_MAIN | NDEBUG_QUEUES,
@@ -2077,7 +2051,6 @@ static void NCR5380_information_transfer
 					    (status_byte(cmd->SCp.Status) == CHECK_CONDITION)) {
 						scsi_eh_prep_cmnd(cmd, &hostdata->ses, NULL, 0, ~0);
 
-						LIST(cmd,hostdata->issue_queue);
 						SET_NEXT(cmd, hostdata->issue_queue);
 						hostdata->issue_queue = (struct scsi_cmnd *) cmd;
 						dsprintk(NDEBUG_AUTOSENSE | NDEBUG_QUEUES,
@@ -2128,7 +2101,6 @@ static void NCR5380_information_transfer
 				case DISCONNECT:
 					/* Accept message by clearing ACK */
 					NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
-					LIST(cmd,hostdata->disconnected_queue);
 					SET_NEXT(cmd, hostdata->disconnected_queue);
 					hostdata->connected = NULL;
 					hostdata->disconnected_queue = cmd;
@@ -2424,10 +2396,8 @@ static void NCR5380_reselect(struct Scsi
 #endif
 		    ) {
 			if (prev) {
-				REMOVE(prev, NEXT(prev), tmp, NEXT(tmp));
 				SET_NEXT(prev, NEXT(tmp));
 			} else {
-				REMOVE(-1, hostdata->disconnected_queue, tmp, NEXT(tmp));
 				hostdata->disconnected_queue = NEXT(tmp);
 			}
 			SET_NEXT(tmp, NULL);
@@ -2597,7 +2567,6 @@ int NCR5380_abort(struct scsi_cmnd *cmd)
 	     tmp = (struct scsi_cmnd *)hostdata->issue_queue;
 	     tmp; prev = NEXTADDR(tmp), tmp = NEXT(tmp)) {
 		if (cmd == tmp) {
-			REMOVE(5, *prev, tmp, NEXT(tmp));
 			(*prev) = NEXT(tmp);
 			SET_NEXT(tmp, NULL);
 			tmp->result = DID_ABORT << 16;
@@ -2671,7 +2640,6 @@ int NCR5380_abort(struct scsi_cmnd *cmd)
 			     tmp = (struct scsi_cmnd *)hostdata->disconnected_queue;
 			     tmp; prev = NEXTADDR(tmp), tmp = NEXT(tmp)) {
 				if (cmd == tmp) {
-					REMOVE(5, *prev, tmp, NEXT(tmp));
 					*prev = NEXT(tmp);
 					SET_NEXT(tmp, NULL);
 					tmp->result = DID_ABORT << 16;



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

* [PATCH 55/71] ncr5380: Remove LIST and REMOVE macros
@ 2015-11-18  8:35   ` Finn Thain
  0 siblings, 0 replies; 268+ messages in thread
From: Finn Thain @ 2015-11-18  8:35 UTC (permalink / raw)
  To: James E.J. Bottomley, Michael Schmitz, linux-m68k, linux-scsi,
	linux-kernel

[-- Attachment #1: ncr5380-remove-LIST-and-REMOVE-macros --]
[-- Type: text/plain, Size: 8548 bytes --]

Printing command pointers can be useful when debugging queues. Other than
that, the LIST and REMOVE macros are just clutter. These macros are
redundant now that NDEBUG_QUEUES causes pointers to be printed, so remove
them.

Signed-off-by: Finn Thain <fthain@telegraphics.com.au>

---
 drivers/scsi/NCR5380.c       |   19 -------------------
 drivers/scsi/atari_NCR5380.c |   32 --------------------------------
 2 files changed, 51 deletions(-)

Index: linux/drivers/scsi/NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/NCR5380.c	2015-11-18 19:34:16.000000000 +1100
+++ linux/drivers/scsi/NCR5380.c	2015-11-18 19:34:18.000000000 +1100
@@ -80,14 +80,6 @@
  *      tagged queueing)
  */
 
-#if (NDEBUG & NDEBUG_LISTS)
-#define LIST(x,y) {printk("LINE:%d   Adding %p to %p\n", __LINE__, (void*)(x), (void*)(y)); if ((x)==(y)) udelay(5); }
-#define REMOVE(w,x,y,z) {printk("LINE:%d   Removing: %p->%p  %p->%p \n", __LINE__, (void*)(w), (void*)(x), (void*)(y), (void*)(z)); if ((x)==(y)) udelay(5); }
-#else
-#define LIST(x,y)
-#define REMOVE(w,x,y,z)
-#endif
-
 #ifndef notyet
 #undef REAL_DMA
 #endif
@@ -774,12 +766,10 @@ static int NCR5380_queue_command(struct
 	 */
 
 	if (!(hostdata->issue_queue) || (cmd->cmnd[0] == REQUEST_SENSE)) {
-		LIST(cmd, hostdata->issue_queue);
 		cmd->host_scribble = (unsigned char *) hostdata->issue_queue;
 		hostdata->issue_queue = cmd;
 	} else {
 		for (tmp = (struct scsi_cmnd *) hostdata->issue_queue; tmp->host_scribble; tmp = (struct scsi_cmnd *) tmp->host_scribble);
-		LIST(cmd, tmp);
 		tmp->host_scribble = (unsigned char *) cmd;
 	}
 	spin_unlock_irqrestore(&hostdata->lock, flags);
@@ -831,10 +821,8 @@ static void NCR5380_main(struct work_str
 				if (!(hostdata->busy[tmp->device->id] &
 				      (1 << (u8)(tmp->device->lun & 0xff)))) {
 					if (prev) {
-						REMOVE(prev, prev->host_scribble, tmp, tmp->host_scribble);
 						prev->host_scribble = tmp->host_scribble;
 					} else {
-						REMOVE(-1, hostdata->issue_queue, tmp, tmp->host_scribble);
 						hostdata->issue_queue = (struct scsi_cmnd *) tmp->host_scribble;
 					}
 					tmp->host_scribble = NULL;
@@ -859,7 +847,6 @@ static void NCR5380_main(struct work_str
 						/* OK or bad target */
 					} else {
 						/* Need to retry */
-						LIST(tmp, hostdata->issue_queue);
 						tmp->host_scribble = (unsigned char *) hostdata->issue_queue;
 						hostdata->issue_queue = tmp;
 						dsprintk(NDEBUG_MAIN | NDEBUG_QUEUES,
@@ -1895,7 +1882,6 @@ static void NCR5380_information_transfer
 					if ((cmd->cmnd[0] != REQUEST_SENSE) && (status_byte(cmd->SCp.Status) == CHECK_CONDITION)) {
 						scsi_eh_prep_cmnd(cmd, &hostdata->ses, NULL, 0, ~0);
 
-						LIST(cmd, hostdata->issue_queue);
 						cmd->host_scribble = (unsigned char *)
 						    hostdata->issue_queue;
 						hostdata->issue_queue = (struct scsi_cmnd *) cmd;
@@ -1932,7 +1918,6 @@ static void NCR5380_information_transfer
 				case DISCONNECT:{
 						/* Accept message by clearing ACK */
 						NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
-						LIST(cmd, hostdata->disconnected_queue);
 						cmd->host_scribble = (unsigned char *)
 						    hostdata->disconnected_queue;
 						hostdata->connected = NULL;
@@ -2182,10 +2167,8 @@ static void NCR5380_reselect(struct Scsi
 	     tmp; prev = tmp, tmp = (struct scsi_cmnd *) tmp->host_scribble) {
 		if ((target_mask == (1 << tmp->device->id)) && (lun == (u8)tmp->device->lun)) {
 			if (prev) {
-				REMOVE(prev, prev->host_scribble, tmp, tmp->host_scribble);
 				prev->host_scribble = tmp->host_scribble;
 			} else {
-				REMOVE(-1, hostdata->disconnected_queue, tmp, tmp->host_scribble);
 				hostdata->disconnected_queue =
 					(struct scsi_cmnd *) tmp->host_scribble;
 			}
@@ -2336,7 +2319,6 @@ static int NCR5380_abort(struct scsi_cmn
 	dprintk(NDEBUG_ABORT, "scsi%d : abort going into loop.\n", instance->host_no);
 	for (prev = (struct scsi_cmnd **) &(hostdata->issue_queue), tmp = (struct scsi_cmnd *) hostdata->issue_queue; tmp; prev = (struct scsi_cmnd **) &(tmp->host_scribble), tmp = (struct scsi_cmnd *) tmp->host_scribble)
 		if (cmd == tmp) {
-			REMOVE(5, *prev, tmp, tmp->host_scribble);
 			(*prev) = (struct scsi_cmnd *) tmp->host_scribble;
 			tmp->host_scribble = NULL;
 			spin_unlock_irqrestore(&hostdata->lock, flags);
@@ -2406,7 +2388,6 @@ static int NCR5380_abort(struct scsi_cmn
 
 			for (prev = (struct scsi_cmnd **) &(hostdata->disconnected_queue), tmp = (struct scsi_cmnd *) hostdata->disconnected_queue; tmp; prev = (struct scsi_cmnd **) &(tmp->host_scribble), tmp = (struct scsi_cmnd *) tmp->host_scribble)
 				if (cmd == tmp) {
-					REMOVE(5, *prev, tmp, tmp->host_scribble);
 					*prev = (struct scsi_cmnd *) tmp->host_scribble;
 					tmp->host_scribble = NULL;
 					spin_unlock_irqrestore(&hostdata->lock, flags);
Index: linux/drivers/scsi/atari_NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/atari_NCR5380.c	2015-11-18 19:34:16.000000000 +1100
+++ linux/drivers/scsi/atari_NCR5380.c	2015-11-18 19:34:18.000000000 +1100
@@ -68,27 +68,6 @@
 
 /* Adapted for the sun3 by Sam Creasey. */
 
-#if (NDEBUG & NDEBUG_LISTS)
-#define LIST(x, y)						\
-	do {							\
-		printk("LINE:%d   Adding %p to %p\n",		\
-		       __LINE__, (void*)(x), (void*)(y));	\
-		if ((x) == (y))					\
-			udelay(5);				\
-	} while (0)
-#define REMOVE(w, x, y, z)					\
-	do {							\
-		printk("LINE:%d   Removing: %p->%p  %p->%p \n",	\
-		       __LINE__, (void*)(w), (void*)(x),	\
-		       (void*)(y), (void*)(z));			\
-		if ((x) == (y))					\
-			udelay(5);				\
-	} while (0)
-#else
-#define LIST(x,y)
-#define REMOVE(w,x,y,z)
-#endif
-
 /*
  * Design
  *
@@ -853,14 +832,12 @@ static int NCR5380_queue_command(struct
 	 */
 
 	if (!(hostdata->issue_queue) || (cmd->cmnd[0] == REQUEST_SENSE)) {
-		LIST(cmd, hostdata->issue_queue);
 		SET_NEXT(cmd, hostdata->issue_queue);
 		hostdata->issue_queue = cmd;
 	} else {
 		for (tmp = (struct scsi_cmnd *)hostdata->issue_queue;
 		     NEXT(tmp); tmp = NEXT(tmp))
 			;
-		LIST(cmd, tmp);
 		SET_NEXT(tmp, cmd);
 	}
 	spin_unlock_irqrestore(&hostdata->lock, flags);
@@ -944,10 +921,8 @@ static void NCR5380_main(struct work_str
 #endif
 				    ) {
 					if (prev) {
-						REMOVE(prev, NEXT(prev), tmp, NEXT(tmp));
 						SET_NEXT(prev, NEXT(tmp));
 					} else {
-						REMOVE(-1, hostdata->issue_queue, tmp, NEXT(tmp));
 						hostdata->issue_queue = NEXT(tmp);
 					}
 					SET_NEXT(tmp, NULL);
@@ -982,7 +957,6 @@ static void NCR5380_main(struct work_str
 						maybe_release_dma_irq(instance);
 					} else {
 						/* Need to retry */
-						LIST(tmp, hostdata->issue_queue);
 						SET_NEXT(tmp, hostdata->issue_queue);
 						hostdata->issue_queue = tmp;
 						dsprintk(NDEBUG_MAIN | NDEBUG_QUEUES,
@@ -2077,7 +2051,6 @@ static void NCR5380_information_transfer
 					    (status_byte(cmd->SCp.Status) == CHECK_CONDITION)) {
 						scsi_eh_prep_cmnd(cmd, &hostdata->ses, NULL, 0, ~0);
 
-						LIST(cmd,hostdata->issue_queue);
 						SET_NEXT(cmd, hostdata->issue_queue);
 						hostdata->issue_queue = (struct scsi_cmnd *) cmd;
 						dsprintk(NDEBUG_AUTOSENSE | NDEBUG_QUEUES,
@@ -2128,7 +2101,6 @@ static void NCR5380_information_transfer
 				case DISCONNECT:
 					/* Accept message by clearing ACK */
 					NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
-					LIST(cmd,hostdata->disconnected_queue);
 					SET_NEXT(cmd, hostdata->disconnected_queue);
 					hostdata->connected = NULL;
 					hostdata->disconnected_queue = cmd;
@@ -2424,10 +2396,8 @@ static void NCR5380_reselect(struct Scsi
 #endif
 		    ) {
 			if (prev) {
-				REMOVE(prev, NEXT(prev), tmp, NEXT(tmp));
 				SET_NEXT(prev, NEXT(tmp));
 			} else {
-				REMOVE(-1, hostdata->disconnected_queue, tmp, NEXT(tmp));
 				hostdata->disconnected_queue = NEXT(tmp);
 			}
 			SET_NEXT(tmp, NULL);
@@ -2597,7 +2567,6 @@ int NCR5380_abort(struct scsi_cmnd *cmd)
 	     tmp = (struct scsi_cmnd *)hostdata->issue_queue;
 	     tmp; prev = NEXTADDR(tmp), tmp = NEXT(tmp)) {
 		if (cmd == tmp) {
-			REMOVE(5, *prev, tmp, NEXT(tmp));
 			(*prev) = NEXT(tmp);
 			SET_NEXT(tmp, NULL);
 			tmp->result = DID_ABORT << 16;
@@ -2671,7 +2640,6 @@ int NCR5380_abort(struct scsi_cmnd *cmd)
 			     tmp = (struct scsi_cmnd *)hostdata->disconnected_queue;
 			     tmp; prev = NEXTADDR(tmp), tmp = NEXT(tmp)) {
 				if (cmd == tmp) {
-					REMOVE(5, *prev, tmp, NEXT(tmp));
 					*prev = NEXT(tmp);
 					SET_NEXT(tmp, NULL);
 					tmp->result = DID_ABORT << 16;

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

* [PATCH 56/71] ncr5380: Remove redundant volatile qualifiers
  2015-11-18  8:34 ` Finn Thain
@ 2015-11-18  8:35   ` Finn Thain
  -1 siblings, 0 replies; 268+ messages in thread
From: Finn Thain @ 2015-11-18  8:35 UTC (permalink / raw)
  To: James E.J. Bottomley, Michael Schmitz, linux-m68k, linux-scsi,
	linux-kernel

[-- Attachment #1: ncr5380-remove-redundant-volatile-qualifiers --]
[-- Type: text/plain, Size: 2220 bytes --]

The hostdata struct is now protected by a spin lock so the volatile
qualifiers are redundant. Remove them.

Signed-off-by: Finn Thain <fthain@telegraphics.com.au>

---
 drivers/scsi/NCR5380.h       |   12 ++++++------
 drivers/scsi/atari_NCR5380.c |    2 +-
 2 files changed, 7 insertions(+), 7 deletions(-)

Index: linux/drivers/scsi/NCR5380.h
===================================================================
--- linux.orig/drivers/scsi/NCR5380.h	2015-11-18 19:34:14.000000000 +1100
+++ linux/drivers/scsi/NCR5380.h	2015-11-18 19:34:19.000000000 +1100
@@ -249,14 +249,14 @@ struct NCR5380_hostdata {
 	NCR5380_implementation_fields;		/* implementation specific */
 	struct Scsi_Host *host;			/* Host backpointer */
 	unsigned char id_mask, id_higher_mask;	/* 1 << id, all bits greater */
-	volatile unsigned char busy[8];		/* index = target, bit = lun */
+	unsigned char busy[8];			/* index = target, bit = lun */
 #if defined(REAL_DMA) || defined(REAL_DMA_POLL)
-	volatile int dma_len;			/* requested length of DMA */
+	int dma_len;				/* requested length of DMA */
 #endif
-	volatile unsigned char last_message;	/* last message OUT */
-	volatile struct scsi_cmnd *connected;	/* currently connected command */
-	volatile struct scsi_cmnd *issue_queue;	/* waiting to be issued */
-	volatile struct scsi_cmnd *disconnected_queue;	/* waiting for reconnect */
+	unsigned char last_message;		/* last message OUT */
+	struct scsi_cmnd *connected;		/* currently connected cmnd */
+	struct scsi_cmnd *issue_queue;		/* waiting to be issued */
+	struct scsi_cmnd *disconnected_queue;	/* waiting for reconnect */
 	spinlock_t lock;			/* protects this struct */
 	int flags;
 	struct scsi_eh_save ses;
Index: linux/drivers/scsi/atari_NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/atari_NCR5380.c	2015-11-18 19:34:18.000000000 +1100
+++ linux/drivers/scsi/atari_NCR5380.c	2015-11-18 19:34:19.000000000 +1100
@@ -1006,7 +1006,7 @@ static void NCR5380_dma_complete(struct
 	struct NCR5380_hostdata *hostdata = shost_priv(instance);
 	int transferred;
 	unsigned char **data;
-	volatile int *count;
+	int *count;
 	int saved_data = 0, overrun = 0;
 	unsigned char p;
 



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

* [PATCH 56/71] ncr5380: Remove redundant volatile qualifiers
@ 2015-11-18  8:35   ` Finn Thain
  0 siblings, 0 replies; 268+ messages in thread
From: Finn Thain @ 2015-11-18  8:35 UTC (permalink / raw)
  To: James E.J. Bottomley, Michael Schmitz, linux-m68k, linux-scsi,
	linux-kernel

[-- Attachment #1: ncr5380-remove-redundant-volatile-qualifiers --]
[-- Type: text/plain, Size: 2218 bytes --]

The hostdata struct is now protected by a spin lock so the volatile
qualifiers are redundant. Remove them.

Signed-off-by: Finn Thain <fthain@telegraphics.com.au>

---
 drivers/scsi/NCR5380.h       |   12 ++++++------
 drivers/scsi/atari_NCR5380.c |    2 +-
 2 files changed, 7 insertions(+), 7 deletions(-)

Index: linux/drivers/scsi/NCR5380.h
===================================================================
--- linux.orig/drivers/scsi/NCR5380.h	2015-11-18 19:34:14.000000000 +1100
+++ linux/drivers/scsi/NCR5380.h	2015-11-18 19:34:19.000000000 +1100
@@ -249,14 +249,14 @@ struct NCR5380_hostdata {
 	NCR5380_implementation_fields;		/* implementation specific */
 	struct Scsi_Host *host;			/* Host backpointer */
 	unsigned char id_mask, id_higher_mask;	/* 1 << id, all bits greater */
-	volatile unsigned char busy[8];		/* index = target, bit = lun */
+	unsigned char busy[8];			/* index = target, bit = lun */
 #if defined(REAL_DMA) || defined(REAL_DMA_POLL)
-	volatile int dma_len;			/* requested length of DMA */
+	int dma_len;				/* requested length of DMA */
 #endif
-	volatile unsigned char last_message;	/* last message OUT */
-	volatile struct scsi_cmnd *connected;	/* currently connected command */
-	volatile struct scsi_cmnd *issue_queue;	/* waiting to be issued */
-	volatile struct scsi_cmnd *disconnected_queue;	/* waiting for reconnect */
+	unsigned char last_message;		/* last message OUT */
+	struct scsi_cmnd *connected;		/* currently connected cmnd */
+	struct scsi_cmnd *issue_queue;		/* waiting to be issued */
+	struct scsi_cmnd *disconnected_queue;	/* waiting for reconnect */
 	spinlock_t lock;			/* protects this struct */
 	int flags;
 	struct scsi_eh_save ses;
Index: linux/drivers/scsi/atari_NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/atari_NCR5380.c	2015-11-18 19:34:18.000000000 +1100
+++ linux/drivers/scsi/atari_NCR5380.c	2015-11-18 19:34:19.000000000 +1100
@@ -1006,7 +1006,7 @@ static void NCR5380_dma_complete(struct
 	struct NCR5380_hostdata *hostdata = shost_priv(instance);
 	int transferred;
 	unsigned char **data;
-	volatile int *count;
+	int *count;
 	int saved_data = 0, overrun = 0;
 	unsigned char p;
 

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

* [PATCH 57/71] ncr5380: Use standard list data structure
  2015-11-18  8:34 ` Finn Thain
  (?)
@ 2015-11-18  8:35   ` Finn Thain
  -1 siblings, 0 replies; 268+ messages in thread
From: Finn Thain @ 2015-11-18  8:35 UTC (permalink / raw)
  To: James E.J. Bottomley, Michael Schmitz, linux-m68k, linux-scsi,
	linux-kernel, Russell King, linux-arm-kernel

[-- Attachment #1: ncr5380-use-list_head --]
[-- Type: text/plain, Size: 34215 bytes --]

The NCR5380 drivers have a home-spun linked list implementation for
scsi_cmnd structs that uses cmd->host_scribble as a 'next' pointer. Adopt
the standard list_head data structure and list operations instead. Remove
the eh_abort_handler rather than convert it. Doing the conversion would
only be churn because the existing EH handlers don't work and get replaced
in a subsequent patch.

Signed-off-by: Finn Thain <fthain@telegraphics.com.au>

---
 drivers/scsi/NCR5380.c       |  214 +++++---------------------------
 drivers/scsi/NCR5380.h       |   16 ++
 drivers/scsi/arm/cumana_1.c  |    1 
 drivers/scsi/arm/oak.c       |    1 
 drivers/scsi/atari_NCR5380.c |  285 ++++++-------------------------------------
 drivers/scsi/atari_scsi.c    |    1 
 drivers/scsi/dmx3191d.c      |    1 
 drivers/scsi/dtc.c           |    1 
 drivers/scsi/g_NCR5380.c     |    1 
 drivers/scsi/mac_scsi.c      |    1 
 drivers/scsi/pas16.c         |    1 
 drivers/scsi/sun3_scsi.c     |    1 
 drivers/scsi/t128.c          |    1 
 13 files changed, 105 insertions(+), 420 deletions(-)

Index: linux/drivers/scsi/NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/NCR5380.c	2015-11-18 19:34:18.000000000 +1100
+++ linux/drivers/scsi/NCR5380.c	2015-11-18 19:34:20.000000000 +1100
@@ -633,8 +633,9 @@ static int NCR5380_init(struct Scsi_Host
 #endif
 	spin_lock_init(&hostdata->lock);
 	hostdata->connected = NULL;
-	hostdata->issue_queue = NULL;
-	hostdata->disconnected_queue = NULL;
+	INIT_LIST_HEAD(&hostdata->unissued);
+	INIT_LIST_HEAD(&hostdata->disconnected);
+
 	hostdata->flags = flags;
 	
 	INIT_WORK(&hostdata->main_task, NCR5380_main);
@@ -734,7 +735,7 @@ static int NCR5380_queue_command(struct
                                  struct scsi_cmnd *cmd)
 {
 	struct NCR5380_hostdata *hostdata = shost_priv(instance);
-	struct scsi_cmnd *tmp;
+	struct NCR5380_cmd *ncmd = scsi_cmd_priv(cmd);
 	unsigned long flags;
 
 #if (NDEBUG & NDEBUG_NO_WRITE)
@@ -748,12 +749,6 @@ static int NCR5380_queue_command(struct
 	}
 #endif				/* (NDEBUG & NDEBUG_NO_WRITE) */
 
-	/* 
-	 * We use the host_scribble field as a pointer to the next command  
-	 * in a queue 
-	 */
-
-	cmd->host_scribble = NULL;
 	cmd->result = 0;
 
 	spin_lock_irqsave(&hostdata->lock, flags);
@@ -765,13 +760,11 @@ static int NCR5380_queue_command(struct
 	 * sense data is only guaranteed to be valid while the condition exists.
 	 */
 
-	if (!(hostdata->issue_queue) || (cmd->cmnd[0] == REQUEST_SENSE)) {
-		cmd->host_scribble = (unsigned char *) hostdata->issue_queue;
-		hostdata->issue_queue = cmd;
-	} else {
-		for (tmp = (struct scsi_cmnd *) hostdata->issue_queue; tmp->host_scribble; tmp = (struct scsi_cmnd *) tmp->host_scribble);
-		tmp->host_scribble = (unsigned char *) cmd;
-	}
+	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",
@@ -799,7 +792,7 @@ static void NCR5380_main(struct work_str
 	struct NCR5380_hostdata *hostdata =
 		container_of(work, struct NCR5380_hostdata, main_task);
 	struct Scsi_Host *instance = hostdata->host;
-	struct scsi_cmnd *tmp, *prev;
+	struct NCR5380_cmd *ncmd, *n;
 	int done;
 	
 	spin_lock_irq(&hostdata->lock);
@@ -812,23 +805,20 @@ static void NCR5380_main(struct work_str
 			 * Search through the issue_queue for a command destined
 			 * for a target that's not busy.
 			 */
-			for (tmp = (struct scsi_cmnd *) hostdata->issue_queue, prev = NULL; tmp; prev = tmp, tmp = (struct scsi_cmnd *) tmp->host_scribble)
-			{
+			list_for_each_entry_safe(ncmd, n, &hostdata->unissued,
+			                         list) {
+				struct scsi_cmnd *tmp = NCR5380_to_scmd(ncmd);
+
 				dsprintk(NDEBUG_QUEUES, instance, "main: tmp=%p target=%d busy=%d lun=%llu\n",
 				         tmp, scmd_id(tmp), hostdata->busy[scmd_id(tmp)],
 				         tmp->device->lun);
 				/*  When we find one, remove it from the issue queue. */
 				if (!(hostdata->busy[tmp->device->id] &
 				      (1 << (u8)(tmp->device->lun & 0xff)))) {
-					if (prev) {
-						prev->host_scribble = tmp->host_scribble;
-					} else {
-						hostdata->issue_queue = (struct scsi_cmnd *) tmp->host_scribble;
-					}
-					tmp->host_scribble = NULL;
+					list_del(&ncmd->list);
 					dsprintk(NDEBUG_MAIN | NDEBUG_QUEUES,
-					         instance, "main: removed %p from issue queue %p\n",
-					         tmp, prev);
+					         instance, "main: removed %p from issue queue\n",
+					         tmp);
 
 					/* 
 					 * Attempt to establish an I_T_L nexus here. 
@@ -847,8 +837,7 @@ static void NCR5380_main(struct work_str
 						/* OK or bad target */
 					} else {
 						/* Need to retry */
-						tmp->host_scribble = (unsigned char *) hostdata->issue_queue;
-						hostdata->issue_queue = tmp;
+						list_add(&ncmd->list, &hostdata->unissued);
 						dsprintk(NDEBUG_MAIN | NDEBUG_QUEUES,
 						         instance, "main: select() failed, %p returned to issue queue\n",
 						         tmp);
@@ -1751,6 +1740,8 @@ static void NCR5380_information_transfer
 	struct scsi_cmnd *cmd;
 
 	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) {
@@ -1882,9 +1873,7 @@ static void NCR5380_information_transfer
 					if ((cmd->cmnd[0] != REQUEST_SENSE) && (status_byte(cmd->SCp.Status) == CHECK_CONDITION)) {
 						scsi_eh_prep_cmnd(cmd, &hostdata->ses, NULL, 0, ~0);
 
-						cmd->host_scribble = (unsigned char *)
-						    hostdata->issue_queue;
-						hostdata->issue_queue = (struct scsi_cmnd *) cmd;
+						list_add(&ncmd->list, &hostdata->unissued);
 						dsprintk(NDEBUG_AUTOSENSE | NDEBUG_QUEUES,
 						         instance, "REQUEST SENSE cmd %p added to head of issue queue\n",
 						         cmd);
@@ -1918,10 +1907,8 @@ static void NCR5380_information_transfer
 				case DISCONNECT:{
 						/* Accept message by clearing ACK */
 						NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
-						cmd->host_scribble = (unsigned char *)
-						    hostdata->disconnected_queue;
 						hostdata->connected = NULL;
-						hostdata->disconnected_queue = cmd;
+						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);
@@ -2094,7 +2081,8 @@ static void NCR5380_reselect(struct Scsi
 	int len;
 	unsigned char msg[3];
 	unsigned char *data;
-	struct scsi_cmnd *tmp = NULL, *prev;
+	struct NCR5380_cmd *ncmd;
+	struct scsi_cmnd *tmp;
 
 	/*
 	 * Disable arbitration, etc. since the host adapter obviously
@@ -2163,16 +2151,14 @@ static void NCR5380_reselect(struct Scsi
 	 * just reestablished, and remove it from the disconnected queue.
 	 */
 
-	for (tmp = (struct scsi_cmnd *) hostdata->disconnected_queue, prev = NULL;
-	     tmp; prev = tmp, tmp = (struct scsi_cmnd *) tmp->host_scribble) {
-		if ((target_mask == (1 << tmp->device->id)) && (lun == (u8)tmp->device->lun)) {
-			if (prev) {
-				prev->host_scribble = tmp->host_scribble;
-			} else {
-				hostdata->disconnected_queue =
-					(struct scsi_cmnd *) tmp->host_scribble;
-			}
-			tmp->host_scribble = NULL;
+	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) {
+			list_del(&ncmd->list);
+			tmp = cmd;
 			break;
 		}
 	}
@@ -2268,146 +2254,18 @@ static int NCR5380_abort(struct scsi_cmn
 {
 	struct Scsi_Host *instance = cmd->device->host;
 	struct NCR5380_hostdata *hostdata = shost_priv(instance);
-	struct scsi_cmnd *tmp, **prev;
 	unsigned long flags;
 
-	scmd_printk(KERN_WARNING, cmd, "aborting command\n");
-
 	spin_lock_irqsave(&hostdata->lock, flags);
 
+#if (NDEBUG & NDEBUG_ANY)
+	scmd_printk(KERN_INFO, cmd, "aborting command\n");
+#endif
 	NCR5380_dprint(NDEBUG_ANY, instance);
 	NCR5380_dprint_phase(NDEBUG_ANY, instance);
 
-	dprintk(NDEBUG_ABORT, "scsi%d : abort called\n", instance->host_no);
-	dprintk(NDEBUG_ABORT, "        basr 0x%X, sr 0x%X\n", NCR5380_read(BUS_AND_STATUS_REG), NCR5380_read(STATUS_REG));
-
-#if 0
-/*
- * Case 1 : If the command is the currently executing command, 
- * we'll set the aborted flag and return control so that 
- * information transfer routine can exit cleanly.
- */
-
-	if (hostdata->connected == cmd) {
-		dprintk(NDEBUG_ABORT, "scsi%d : aborting connected command\n", instance->host_no);
-/*
- * We should perform BSY checking, and make sure we haven't slipped
- * into BUS FREE.
- */
-
-		NCR5380_write(INITIATOR_COMMAND_REG, ICR_ASSERT_ATN);
-/* 
- * Since we can't change phases until we've completed the current 
- * handshake, we have to source or sink a byte of data if the current
- * phase is not MSGOUT.
- */
-
-/* 
- * Return control to the executing NCR drive so we can clear the
- * aborted flag and get back into our main loop.
- */
-
-		return SUCCESS;
-	}
-#endif
-
-/* 
- * Case 2 : If the command hasn't been issued yet, we simply remove it 
- *          from the issue queue.
- */
- 
-	dprintk(NDEBUG_ABORT, "scsi%d : abort going into loop.\n", instance->host_no);
-	for (prev = (struct scsi_cmnd **) &(hostdata->issue_queue), tmp = (struct scsi_cmnd *) hostdata->issue_queue; tmp; prev = (struct scsi_cmnd **) &(tmp->host_scribble), tmp = (struct scsi_cmnd *) tmp->host_scribble)
-		if (cmd == tmp) {
-			(*prev) = (struct scsi_cmnd *) tmp->host_scribble;
-			tmp->host_scribble = NULL;
-			spin_unlock_irqrestore(&hostdata->lock, flags);
-			tmp->result = DID_ABORT << 16;
-			dprintk(NDEBUG_ABORT, "scsi%d : abort removed command from issue queue.\n", instance->host_no);
-			tmp->scsi_done(tmp);
-			return SUCCESS;
-		}
-#if (NDEBUG  & NDEBUG_ABORT)
-	/* KLL */
-		else if (prev == tmp)
-			printk(KERN_ERR "scsi%d : LOOP\n", instance->host_no);
-#endif
-
-/* 
- * Case 3 : If any commands are connected, we're going to fail the abort
- *          and let the high level SCSI driver retry at a later time or 
- *          issue a reset.
- *
- *          Timeouts, and therefore aborted commands, will be highly unlikely
- *          and handling them cleanly in this situation would make the common
- *          case of noresets less efficient, and would pollute our code.  So,
- *          we fail.
- */
-
-	if (hostdata->connected) {
-		spin_unlock_irqrestore(&hostdata->lock, flags);
-		dprintk(NDEBUG_ABORT, "scsi%d : abort failed, command connected.\n", instance->host_no);
-		return FAILED;
-	}
-/*
- * Case 4: If the command is currently disconnected from the bus, and 
- *      there are no connected commands, we reconnect the I_T_L or 
- *      I_T_L_Q nexus associated with it, go into message out, and send 
- *      an abort message.
- *
- * This case is especially ugly. In order to reestablish the nexus, we
- * need to call NCR5380_select().  The easiest way to implement this 
- * function was to abort if the bus was busy, and let the interrupt
- * handler triggered on the SEL for reselect take care of lost arbitrations
- * where necessary, meaning interrupts need to be enabled.
- *
- * When interrupts are enabled, the queues may change - so we 
- * can't remove it from the disconnected queue before selecting it
- * because that could cause a failure in hashing the nexus if that 
- * device reselected.
- * 
- * Since the queues may change, we can't use the pointers from when we
- * first locate it.
- *
- * So, we must first locate the command, and if NCR5380_select()
- * succeeds, then issue the abort, relocate the command and remove
- * it from the disconnected queue.
- */
-
-	for (tmp = (struct scsi_cmnd *) hostdata->disconnected_queue; tmp; tmp = (struct scsi_cmnd *) tmp->host_scribble)
-		if (cmd == tmp) {
-			dprintk(NDEBUG_ABORT, "scsi%d : aborting disconnected command.\n", instance->host_no);
-
-			if (NCR5380_select(instance, cmd)) {
-				spin_unlock_irq(&hostdata->lock);
-				return FAILED;
-			}
-			dprintk(NDEBUG_ABORT, "scsi%d : nexus reestablished.\n", instance->host_no);
-
-			do_abort(instance);
-
-			for (prev = (struct scsi_cmnd **) &(hostdata->disconnected_queue), tmp = (struct scsi_cmnd *) hostdata->disconnected_queue; tmp; prev = (struct scsi_cmnd **) &(tmp->host_scribble), tmp = (struct scsi_cmnd *) tmp->host_scribble)
-				if (cmd == tmp) {
-					*prev = (struct scsi_cmnd *) tmp->host_scribble;
-					tmp->host_scribble = NULL;
-					spin_unlock_irqrestore(&hostdata->lock, flags);
-					tmp->result = DID_ABORT << 16;
-					tmp->scsi_done(tmp);
-					return SUCCESS;
-				}
-		}
-/*
- * Case 5 : If we reached this point, the command was not found in any of 
- *          the queues.
- *
- * We probably reached this point because of an unlikely race condition
- * between the command completing successfully and the abortion code,
- * so we won't panic, but we will notify the user in case something really
- * broke.
- */
 	spin_unlock_irqrestore(&hostdata->lock, flags);
-	printk(KERN_WARNING "scsi%d : warning : SCSI command probably completed successfully\n"
-			"         before abortion\n", instance->host_no);
+
 	return FAILED;
 }
 
Index: linux/drivers/scsi/atari_NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/atari_NCR5380.c	2015-11-18 19:34:19.000000000 +1100
+++ linux/drivers/scsi/atari_NCR5380.c	2015-11-18 19:34:20.000000000 +1100
@@ -175,10 +175,6 @@
  * possible) function may be used.
  */
 
-#define	NEXT(cmd)		((struct scsi_cmnd *)(cmd)->host_scribble)
-#define	SET_NEXT(cmd,next)	((cmd)->host_scribble = (void *)(next))
-#define	NEXTADDR(cmd)		((struct scsi_cmnd **)&(cmd)->host_scribble)
-
 #define	HOSTNO		instance->host_no
 
 static int do_abort(struct Scsi_Host *);
@@ -676,8 +672,9 @@ static int __init NCR5380_init(struct Sc
 #endif
 	spin_lock_init(&hostdata->lock);
 	hostdata->connected = NULL;
-	hostdata->issue_queue = NULL;
-	hostdata->disconnected_queue = NULL;
+	INIT_LIST_HEAD(&hostdata->unissued);
+	INIT_LIST_HEAD(&hostdata->disconnected);
+
 	hostdata->flags = flags;
 
 	INIT_WORK(&hostdata->main_task, NCR5380_main);
@@ -778,7 +775,7 @@ static int NCR5380_queue_command(struct
                                  struct scsi_cmnd *cmd)
 {
 	struct NCR5380_hostdata *hostdata = shost_priv(instance);
-	struct scsi_cmnd *tmp;
+	struct NCR5380_cmd *ncmd = scsi_cmd_priv(cmd);
 	unsigned long flags;
 
 #if (NDEBUG & NDEBUG_NO_WRITE)
@@ -792,12 +789,6 @@ static int NCR5380_queue_command(struct
 	}
 #endif /* (NDEBUG & NDEBUG_NO_WRITE) */
 
-	/*
-	 * We use the host_scribble field as a pointer to the next command
-	 * in a queue
-	 */
-
-	SET_NEXT(cmd, NULL);
 	cmd->result = 0;
 
 	/*
@@ -831,15 +822,11 @@ static int NCR5380_queue_command(struct
 	 * sense data is only guaranteed to be valid while the condition exists.
 	 */
 
-	if (!(hostdata->issue_queue) || (cmd->cmnd[0] == REQUEST_SENSE)) {
-		SET_NEXT(cmd, hostdata->issue_queue);
-		hostdata->issue_queue = cmd;
-	} else {
-		for (tmp = (struct scsi_cmnd *)hostdata->issue_queue;
-		     NEXT(tmp); tmp = NEXT(tmp))
-			;
-		SET_NEXT(tmp, cmd);
-	}
+	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",
@@ -855,8 +842,8 @@ static inline void maybe_release_dma_irq
 	struct NCR5380_hostdata *hostdata = shost_priv(instance);
 
 	/* Caller does the locking needed to set & test these data atomically */
-	if (!hostdata->disconnected_queue &&
-	    !hostdata->issue_queue &&
+	if (list_empty(&hostdata->disconnected) &&
+	    list_empty(&hostdata->unissued) &&
 	    !hostdata->connected &&
 	    !hostdata->retain_dma_intr)
 		NCR5380_release_dma_irq(instance);
@@ -878,7 +865,7 @@ static void NCR5380_main(struct work_str
 	struct NCR5380_hostdata *hostdata =
 		container_of(work, struct NCR5380_hostdata, main_task);
 	struct Scsi_Host *instance = hostdata->host;
-	struct scsi_cmnd *tmp, *prev;
+	struct NCR5380_cmd *ncmd, *n;
 	int done;
 
 	/*
@@ -897,17 +884,9 @@ static void NCR5380_main(struct work_str
 			 * Search through the issue_queue for a command destined
 			 * for a target that's not busy.
 			 */
-#if (NDEBUG & NDEBUG_LISTS)
-			for (tmp = (struct scsi_cmnd *) hostdata->issue_queue, prev = NULL;
-			     tmp && (tmp != prev); prev = tmp, tmp = NEXT(tmp))
-				;
-			/*printk("%p  ", tmp);*/
-			if ((tmp == prev) && tmp)
-				printk(" LOOP\n");
-			/* else printk("\n"); */
-#endif
-			for (tmp = (struct scsi_cmnd *) hostdata->issue_queue,
-			     prev = NULL; tmp; prev = tmp, tmp = NEXT(tmp)) {
+			list_for_each_entry_safe(ncmd, n, &hostdata->unissued,
+			                         list) {
+				struct scsi_cmnd *tmp = NCR5380_to_scmd(ncmd);
 				u8 lun = tmp->device->lun;
 
 				dsprintk(NDEBUG_QUEUES, instance, "main: tmp=%p target=%d busy=%d lun=%d\n",
@@ -920,15 +899,10 @@ static void NCR5380_main(struct work_str
 				    !(hostdata->busy[tmp->device->id] & (1 << lun))
 #endif
 				    ) {
-					if (prev) {
-						SET_NEXT(prev, NEXT(tmp));
-					} else {
-						hostdata->issue_queue = NEXT(tmp);
-					}
-					SET_NEXT(tmp, NULL);
+					list_del(&ncmd->list);
 					dsprintk(NDEBUG_MAIN | NDEBUG_QUEUES,
-					         instance, "main: removed %p from issue queue %p\n",
-					         tmp, prev);
+					         instance, "main: removed %p from issue queue\n",
+					         tmp);
 
 					hostdata->retain_dma_intr++;
 
@@ -957,8 +931,7 @@ static void NCR5380_main(struct work_str
 						maybe_release_dma_irq(instance);
 					} else {
 						/* Need to retry */
-						SET_NEXT(tmp, hostdata->issue_queue);
-						hostdata->issue_queue = tmp;
+						list_add(&ncmd->list, &hostdata->unissued);
 						dsprintk(NDEBUG_MAIN | NDEBUG_QUEUES,
 						         instance, "main: select() failed, %p returned to issue queue\n",
 						         tmp);
@@ -1843,6 +1816,8 @@ static void NCR5380_information_transfer
 #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) {
@@ -2051,8 +2026,7 @@ static void NCR5380_information_transfer
 					    (status_byte(cmd->SCp.Status) == CHECK_CONDITION)) {
 						scsi_eh_prep_cmnd(cmd, &hostdata->ses, NULL, 0, ~0);
 
-						SET_NEXT(cmd, hostdata->issue_queue);
-						hostdata->issue_queue = (struct scsi_cmnd *) cmd;
+						list_add(&ncmd->list, &hostdata->unissued);
 						dsprintk(NDEBUG_AUTOSENSE | NDEBUG_QUEUES,
 						         instance, "REQUEST SENSE cmd %p added to head of issue queue\n",
 						         cmd);
@@ -2101,9 +2075,8 @@ static void NCR5380_information_transfer
 				case DISCONNECT:
 					/* Accept message by clearing ACK */
 					NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
-					SET_NEXT(cmd, hostdata->disconnected_queue);
 					hostdata->connected = NULL;
-					hostdata->disconnected_queue = cmd;
+					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);
@@ -2297,7 +2270,8 @@ static void NCR5380_reselect(struct Scsi
 	unsigned char msg[3];
 	int __maybe_unused len;
 	unsigned char __maybe_unused *data, __maybe_unused phase;
-	struct scsi_cmnd *tmp = NULL, *prev;
+	struct NCR5380_cmd *ncmd;
+	struct scsi_cmnd *tmp;
 
 	/*
 	 * Disable arbitration, etc. since the host adapter obviously
@@ -2388,19 +2362,18 @@ static void NCR5380_reselect(struct Scsi
 	 * just reestablished, and remove it from the disconnected queue.
 	 */
 
-	for (tmp = (struct scsi_cmnd *) hostdata->disconnected_queue, prev = NULL;
-	     tmp; prev = tmp, tmp = NEXT(tmp)) {
-		if ((target_mask == (1 << tmp->device->id)) && (lun == (u8)tmp->device->lun)
+	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 == tmp->tag)
 #endif
 		    ) {
-			if (prev) {
-				SET_NEXT(prev, NEXT(tmp));
-			} else {
-				hostdata->disconnected_queue = NEXT(tmp);
-			}
-			SET_NEXT(tmp, NULL);
+			list_del(&ncmd->list);
+			tmp = cmd;
 			break;
 		}
 	}
@@ -2498,188 +2471,18 @@ int NCR5380_abort(struct scsi_cmnd *cmd)
 {
 	struct Scsi_Host *instance = cmd->device->host;
 	struct NCR5380_hostdata *hostdata = shost_priv(instance);
-	struct scsi_cmnd *tmp, **prev;
 	unsigned long flags;
 
-	scmd_printk(KERN_NOTICE, cmd, "aborting command\n");
-
 	spin_lock_irqsave(&hostdata->lock, flags);
 
+#if (NDEBUG & NDEBUG_ANY)
+	scmd_printk(KERN_INFO, cmd, "aborting command\n");
+#endif
 	NCR5380_dprint(NDEBUG_ANY, instance);
 	NCR5380_dprint_phase(NDEBUG_ANY, instance);
 
-	dprintk(NDEBUG_ABORT, "scsi%d: abort called basr 0x%02x, sr 0x%02x\n", HOSTNO,
-		    NCR5380_read(BUS_AND_STATUS_REG),
-		    NCR5380_read(STATUS_REG));
-
-#if 1
-	/*
-	 * Case 1 : If the command is the currently executing command,
-	 * we'll set the aborted flag and return control so that
-	 * information transfer routine can exit cleanly.
-	 */
-
-	if (hostdata->connected == cmd) {
-
-		dprintk(NDEBUG_ABORT, "scsi%d: aborting connected command\n", HOSTNO);
-		/*
-		 * We should perform BSY checking, and make sure we haven't slipped
-		 * into BUS FREE.
-		 */
-
-		/*	NCR5380_write(INITIATOR_COMMAND_REG, ICR_ASSERT_ATN); */
-		/*
-		 * Since we can't change phases until we've completed the current
-		 * handshake, we have to source or sink a byte of data if the current
-		 * phase is not MSGOUT.
-		 */
-
-		/*
-		 * Return control to the executing NCR drive so we can clear the
-		 * aborted flag and get back into our main loop.
-		 */
-
-		if (do_abort(instance) == 0) {
-			hostdata->connected = NULL;
-			cmd->result = DID_ABORT << 16;
-#ifdef SUPPORT_TAGS
-			cmd_free_tag(cmd);
-#else
-			hostdata->busy[cmd->device->id] &= ~(1 << cmd->device->lun);
-#endif
-			maybe_release_dma_irq(instance);
-			spin_unlock_irqrestore(&hostdata->lock, flags);
-			cmd->scsi_done(cmd);
-			return SUCCESS;
-		} else {
-			spin_unlock_irqrestore(&hostdata->lock, flags);
-			printk("scsi%d: abort of connected command failed!\n", HOSTNO);
-			return FAILED;
-		}
-	}
-#endif
-
-	/*
-	 * Case 2 : If the command hasn't been issued yet, we simply remove it
-	 *	    from the issue queue.
-	 */
-	for (prev = (struct scsi_cmnd **)&(hostdata->issue_queue),
-	     tmp = (struct scsi_cmnd *)hostdata->issue_queue;
-	     tmp; prev = NEXTADDR(tmp), tmp = NEXT(tmp)) {
-		if (cmd == tmp) {
-			(*prev) = NEXT(tmp);
-			SET_NEXT(tmp, NULL);
-			tmp->result = DID_ABORT << 16;
-			maybe_release_dma_irq(instance);
-			spin_unlock_irqrestore(&hostdata->lock, flags);
-			dprintk(NDEBUG_ABORT, "scsi%d: abort removed command from issue queue.\n",
-				    HOSTNO);
-			/* Tagged queuing note: no tag to free here, hasn't been assigned
-			 * yet... */
-			tmp->scsi_done(tmp);
-			return SUCCESS;
-		}
-	}
-
-	/*
-	 * Case 3 : If any commands are connected, we're going to fail the abort
-	 *	    and let the high level SCSI driver retry at a later time or
-	 *	    issue a reset.
-	 *
-	 *	    Timeouts, and therefore aborted commands, will be highly unlikely
-	 *          and handling them cleanly in this situation would make the common
-	 *	    case of noresets less efficient, and would pollute our code.  So,
-	 *	    we fail.
-	 */
-
-	if (hostdata->connected) {
-		spin_unlock_irqrestore(&hostdata->lock, flags);
-		dprintk(NDEBUG_ABORT, "scsi%d: abort failed, command connected.\n", HOSTNO);
-		return FAILED;
-	}
-
-	/*
-	 * Case 4: If the command is currently disconnected from the bus, and
-	 *	there are no connected commands, we reconnect the I_T_L or
-	 *	I_T_L_Q nexus associated with it, go into message out, and send
-	 *      an abort message.
-	 *
-	 * This case is especially ugly. In order to reestablish the nexus, we
-	 * need to call NCR5380_select().  The easiest way to implement this
-	 * function was to abort if the bus was busy, and let the interrupt
-	 * handler triggered on the SEL for reselect take care of lost arbitrations
-	 * where necessary, meaning interrupts need to be enabled.
-	 *
-	 * When interrupts are enabled, the queues may change - so we
-	 * can't remove it from the disconnected queue before selecting it
-	 * because that could cause a failure in hashing the nexus if that
-	 * device reselected.
-	 *
-	 * Since the queues may change, we can't use the pointers from when we
-	 * first locate it.
-	 *
-	 * So, we must first locate the command, and if NCR5380_select()
-	 * succeeds, then issue the abort, relocate the command and remove
-	 * it from the disconnected queue.
-	 */
-
-	for (tmp = (struct scsi_cmnd *) hostdata->disconnected_queue; tmp;
-	     tmp = NEXT(tmp)) {
-		if (cmd == tmp) {
-			dprintk(NDEBUG_ABORT, "scsi%d: aborting disconnected command.\n", HOSTNO);
-
-			if (NCR5380_select(instance, cmd)) {
-				spin_unlock_irq(&hostdata->lock);
-				return FAILED;
-			}
-			dprintk(NDEBUG_ABORT, "scsi%d: nexus reestablished.\n", HOSTNO);
-
-			do_abort(instance);
-
-			for (prev = (struct scsi_cmnd **)&(hostdata->disconnected_queue),
-			     tmp = (struct scsi_cmnd *)hostdata->disconnected_queue;
-			     tmp; prev = NEXTADDR(tmp), tmp = NEXT(tmp)) {
-				if (cmd == tmp) {
-					*prev = NEXT(tmp);
-					SET_NEXT(tmp, NULL);
-					tmp->result = DID_ABORT << 16;
-					/* We must unlock the tag/LUN immediately here, since the
-					 * target goes to BUS FREE and doesn't send us another
-					 * message (COMMAND_COMPLETE or the like)
-					 */
-#ifdef SUPPORT_TAGS
-					cmd_free_tag(tmp);
-#else
-					hostdata->busy[cmd->device->id] &= ~(1 << cmd->device->lun);
-#endif
-					maybe_release_dma_irq(instance);
-					spin_unlock_irqrestore(&hostdata->lock, flags);
-					tmp->scsi_done(tmp);
-					return SUCCESS;
-				}
-			}
-		}
-	}
-
-	/* Maybe it is sufficient just to release the ST-DMA lock... (if
-	 * possible at all) At least, we should check if the lock could be
-	 * released after the abort, in case it is kept due to some bug.
-	 */
-	maybe_release_dma_irq(instance);
 	spin_unlock_irqrestore(&hostdata->lock, flags);
 
-	/*
-	 * Case 5 : If we reached this point, the command was not found in any of
-	 *	    the queues.
-	 *
-	 * We probably reached this point because of an unlikely race condition
-	 * between the command completing successfully and the abortion code,
-	 * so we won't panic, but we will notify the user in case something really
-	 * broke.
-	 */
-
-	printk(KERN_INFO "scsi%d: warning : SCSI command probably completed successfully before abortion\n", HOSTNO);
-
 	return FAILED;
 }
 
@@ -2719,16 +2522,18 @@ static int NCR5380_bus_reset(struct scsi
 	 * commands!
 	 */
 
-	if (hostdata->issue_queue)
-		dsprintk(NDEBUG_ABORT, instance, "reset aborted issued command(s)\n");
 	if (hostdata->connected)
 		dsprintk(NDEBUG_ABORT, instance, "reset aborted a connected command\n");
-	if (hostdata->disconnected_queue)
-		dsprintk(NDEBUG_ABORT, instance, "reset aborted disconnected command(s)\n");
-
-	hostdata->issue_queue = NULL;
 	hostdata->connected = NULL;
-	hostdata->disconnected_queue = NULL;
+
+	if (!list_empty(&hostdata->unissued))
+		dsprintk(NDEBUG_ABORT, instance, "reset aborted unissued list\n");
+	INIT_LIST_HEAD(&hostdata->unissued);
+
+	if (!list_empty(&hostdata->disconnected))
+		dsprintk(NDEBUG_ABORT, instance, "reset aborted disconnected list\n");
+	INIT_LIST_HEAD(&hostdata->disconnected);
+
 #ifdef SUPPORT_TAGS
 	free_all_tags(hostdata);
 #endif
Index: linux/drivers/scsi/NCR5380.h
===================================================================
--- linux.orig/drivers/scsi/NCR5380.h	2015-11-18 19:34:19.000000000 +1100
+++ linux/drivers/scsi/NCR5380.h	2015-11-18 19:34:20.000000000 +1100
@@ -24,6 +24,7 @@
 
 #include <linux/delay.h>
 #include <linux/interrupt.h>
+#include <linux/list.h>
 #include <linux/workqueue.h>
 #include <scsi/scsi_dbg.h>
 #include <scsi/scsi_eh.h>
@@ -255,8 +256,8 @@ struct NCR5380_hostdata {
 #endif
 	unsigned char last_message;		/* last message OUT */
 	struct scsi_cmnd *connected;		/* currently connected cmnd */
-	struct scsi_cmnd *issue_queue;		/* waiting to be issued */
-	struct scsi_cmnd *disconnected_queue;	/* waiting for reconnect */
+	struct list_head unissued;		/* waiting to be issued */
+	struct list_head disconnected;		/* waiting for reconnect */
 	spinlock_t lock;			/* protects this struct */
 	int flags;
 	struct scsi_eh_save ses;
@@ -277,6 +278,17 @@ struct NCR5380_hostdata {
 
 #ifdef __KERNEL__
 
+struct NCR5380_cmd {
+	struct list_head list;
+};
+
+#define NCR5380_CMD_SIZE		(sizeof(struct NCR5380_cmd))
+
+static inline struct scsi_cmnd *NCR5380_to_scmd(struct NCR5380_cmd *ncmd_ptr)
+{
+	return ((struct scsi_cmnd *)ncmd_ptr) - 1;
+}
+
 #ifndef NDEBUG
 #define NDEBUG (0)
 #endif
Index: linux/drivers/scsi/arm/cumana_1.c
===================================================================
--- linux.orig/drivers/scsi/arm/cumana_1.c	2015-11-18 19:34:01.000000000 +1100
+++ linux/drivers/scsi/arm/cumana_1.c	2015-11-18 19:34:20.000000000 +1100
@@ -208,6 +208,7 @@ static struct scsi_host_template cumanas
 	.cmd_per_lun		= 2,
 	.use_clustering		= DISABLE_CLUSTERING,
 	.proc_name		= "CumanaSCSI-1",
+	.cmd_size		= NCR5380_CMD_SIZE,
 };
 
 static int cumanascsi1_probe(struct expansion_card *ec,
Index: linux/drivers/scsi/arm/oak.c
===================================================================
--- linux.orig/drivers/scsi/arm/oak.c	2015-11-18 19:34:12.000000000 +1100
+++ linux/drivers/scsi/arm/oak.c	2015-11-18 19:34:20.000000000 +1100
@@ -114,6 +114,7 @@ static struct scsi_host_template oakscsi
 	.cmd_per_lun		= 2,
 	.use_clustering		= DISABLE_CLUSTERING,
 	.proc_name		= "oakscsi",
+	.cmd_size		= NCR5380_CMD_SIZE,
 };
 
 static int oakscsi_probe(struct expansion_card *ec, const struct ecard_id *id)
Index: linux/drivers/scsi/atari_scsi.c
===================================================================
--- linux.orig/drivers/scsi/atari_scsi.c	2015-11-18 19:34:12.000000000 +1100
+++ linux/drivers/scsi/atari_scsi.c	2015-11-18 19:34:20.000000000 +1100
@@ -780,6 +780,7 @@ static struct scsi_host_template atari_s
 	.eh_bus_reset_handler	= atari_scsi_bus_reset,
 	.this_id		= 7,
 	.use_clustering		= DISABLE_CLUSTERING,
+	.cmd_size		= NCR5380_CMD_SIZE,
 };
 
 static int __init atari_scsi_probe(struct platform_device *pdev)
Index: linux/drivers/scsi/dmx3191d.c
===================================================================
--- linux.orig/drivers/scsi/dmx3191d.c	2015-11-18 19:34:05.000000000 +1100
+++ linux/drivers/scsi/dmx3191d.c	2015-11-18 19:34:20.000000000 +1100
@@ -61,6 +61,7 @@ static struct scsi_host_template dmx3191
 	.sg_tablesize		= SG_ALL,
 	.cmd_per_lun		= 2,
 	.use_clustering		= DISABLE_CLUSTERING,
+	.cmd_size		= NCR5380_CMD_SIZE,
 };
 
 static int dmx3191d_probe_one(struct pci_dev *pdev,
Index: linux/drivers/scsi/dtc.c
===================================================================
--- linux.orig/drivers/scsi/dtc.c	2015-11-18 19:34:05.000000000 +1100
+++ linux/drivers/scsi/dtc.c	2015-11-18 19:34:20.000000000 +1100
@@ -452,5 +452,6 @@ static struct scsi_host_template driver_
 	.sg_tablesize		= SG_ALL,
 	.cmd_per_lun		= 2,
 	.use_clustering		= DISABLE_CLUSTERING,
+	.cmd_size		= NCR5380_CMD_SIZE,
 };
 #include "scsi_module.c"
Index: linux/drivers/scsi/g_NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/g_NCR5380.c	2015-11-18 19:34:12.000000000 +1100
+++ linux/drivers/scsi/g_NCR5380.c	2015-11-18 19:34:20.000000000 +1100
@@ -729,6 +729,7 @@ static struct scsi_host_template driver_
 	.sg_tablesize		= SG_ALL,
 	.cmd_per_lun		= 2,
 	.use_clustering		= DISABLE_CLUSTERING,
+	.cmd_size		= NCR5380_CMD_SIZE,
 };
 
 #include "scsi_module.c"
Index: linux/drivers/scsi/mac_scsi.c
===================================================================
--- linux.orig/drivers/scsi/mac_scsi.c	2015-11-18 19:34:05.000000000 +1100
+++ linux/drivers/scsi/mac_scsi.c	2015-11-18 19:34:20.000000000 +1100
@@ -323,6 +323,7 @@ static struct scsi_host_template mac_scs
 	.sg_tablesize		= SG_ALL,
 	.cmd_per_lun		= 2,
 	.use_clustering		= DISABLE_CLUSTERING,
+	.cmd_size		= NCR5380_CMD_SIZE,
 };
 
 static int __init mac_scsi_probe(struct platform_device *pdev)
Index: linux/drivers/scsi/pas16.c
===================================================================
--- linux.orig/drivers/scsi/pas16.c	2015-11-18 19:34:05.000000000 +1100
+++ linux/drivers/scsi/pas16.c	2015-11-18 19:34:20.000000000 +1100
@@ -562,6 +562,7 @@ static struct scsi_host_template driver_
 	.sg_tablesize		= SG_ALL,
 	.cmd_per_lun		= 2,
 	.use_clustering		= DISABLE_CLUSTERING,
+	.cmd_size		= NCR5380_CMD_SIZE,
 };
 #include "scsi_module.c"
 
Index: linux/drivers/scsi/sun3_scsi.c
===================================================================
--- linux.orig/drivers/scsi/sun3_scsi.c	2015-11-18 19:34:12.000000000 +1100
+++ linux/drivers/scsi/sun3_scsi.c	2015-11-18 19:34:20.000000000 +1100
@@ -468,6 +468,7 @@ static struct scsi_host_template sun3_sc
 	.sg_tablesize		= SG_NONE,
 	.cmd_per_lun		= 2,
 	.use_clustering		= DISABLE_CLUSTERING,
+	.cmd_size		= NCR5380_CMD_SIZE,
 };
 
 static int __init sun3_scsi_probe(struct platform_device *pdev)
Index: linux/drivers/scsi/t128.c
===================================================================
--- linux.orig/drivers/scsi/t128.c	2015-11-18 19:34:05.000000000 +1100
+++ linux/drivers/scsi/t128.c	2015-11-18 19:34:20.000000000 +1100
@@ -406,5 +406,6 @@ static struct scsi_host_template driver_
 	.sg_tablesize		= SG_ALL,
 	.cmd_per_lun		= 2,
 	.use_clustering		= DISABLE_CLUSTERING,
+	.cmd_size		= NCR5380_CMD_SIZE,
 };
 #include "scsi_module.c"



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

* [PATCH 57/71] ncr5380: Use standard list data structure
@ 2015-11-18  8:35   ` Finn Thain
  0 siblings, 0 replies; 268+ messages in thread
From: Finn Thain @ 2015-11-18  8:35 UTC (permalink / raw)
  To: James E.J. Bottomley, Michael Schmitz, linux-m68k, linux-scsi,
	linux-kernel, Russell King, linux-arm-kernel

[-- Attachment #1: ncr5380-use-list_head --]
[-- Type: text/plain, Size: 34213 bytes --]

The NCR5380 drivers have a home-spun linked list implementation for
scsi_cmnd structs that uses cmd->host_scribble as a 'next' pointer. Adopt
the standard list_head data structure and list operations instead. Remove
the eh_abort_handler rather than convert it. Doing the conversion would
only be churn because the existing EH handlers don't work and get replaced
in a subsequent patch.

Signed-off-by: Finn Thain <fthain@telegraphics.com.au>

---
 drivers/scsi/NCR5380.c       |  214 +++++---------------------------
 drivers/scsi/NCR5380.h       |   16 ++
 drivers/scsi/arm/cumana_1.c  |    1 
 drivers/scsi/arm/oak.c       |    1 
 drivers/scsi/atari_NCR5380.c |  285 ++++++-------------------------------------
 drivers/scsi/atari_scsi.c    |    1 
 drivers/scsi/dmx3191d.c      |    1 
 drivers/scsi/dtc.c           |    1 
 drivers/scsi/g_NCR5380.c     |    1 
 drivers/scsi/mac_scsi.c      |    1 
 drivers/scsi/pas16.c         |    1 
 drivers/scsi/sun3_scsi.c     |    1 
 drivers/scsi/t128.c          |    1 
 13 files changed, 105 insertions(+), 420 deletions(-)

Index: linux/drivers/scsi/NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/NCR5380.c	2015-11-18 19:34:18.000000000 +1100
+++ linux/drivers/scsi/NCR5380.c	2015-11-18 19:34:20.000000000 +1100
@@ -633,8 +633,9 @@ static int NCR5380_init(struct Scsi_Host
 #endif
 	spin_lock_init(&hostdata->lock);
 	hostdata->connected = NULL;
-	hostdata->issue_queue = NULL;
-	hostdata->disconnected_queue = NULL;
+	INIT_LIST_HEAD(&hostdata->unissued);
+	INIT_LIST_HEAD(&hostdata->disconnected);
+
 	hostdata->flags = flags;
 	
 	INIT_WORK(&hostdata->main_task, NCR5380_main);
@@ -734,7 +735,7 @@ static int NCR5380_queue_command(struct
                                  struct scsi_cmnd *cmd)
 {
 	struct NCR5380_hostdata *hostdata = shost_priv(instance);
-	struct scsi_cmnd *tmp;
+	struct NCR5380_cmd *ncmd = scsi_cmd_priv(cmd);
 	unsigned long flags;
 
 #if (NDEBUG & NDEBUG_NO_WRITE)
@@ -748,12 +749,6 @@ static int NCR5380_queue_command(struct
 	}
 #endif				/* (NDEBUG & NDEBUG_NO_WRITE) */
 
-	/* 
-	 * We use the host_scribble field as a pointer to the next command  
-	 * in a queue 
-	 */
-
-	cmd->host_scribble = NULL;
 	cmd->result = 0;
 
 	spin_lock_irqsave(&hostdata->lock, flags);
@@ -765,13 +760,11 @@ static int NCR5380_queue_command(struct
 	 * sense data is only guaranteed to be valid while the condition exists.
 	 */
 
-	if (!(hostdata->issue_queue) || (cmd->cmnd[0] == REQUEST_SENSE)) {
-		cmd->host_scribble = (unsigned char *) hostdata->issue_queue;
-		hostdata->issue_queue = cmd;
-	} else {
-		for (tmp = (struct scsi_cmnd *) hostdata->issue_queue; tmp->host_scribble; tmp = (struct scsi_cmnd *) tmp->host_scribble);
-		tmp->host_scribble = (unsigned char *) cmd;
-	}
+	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",
@@ -799,7 +792,7 @@ static void NCR5380_main(struct work_str
 	struct NCR5380_hostdata *hostdata =
 		container_of(work, struct NCR5380_hostdata, main_task);
 	struct Scsi_Host *instance = hostdata->host;
-	struct scsi_cmnd *tmp, *prev;
+	struct NCR5380_cmd *ncmd, *n;
 	int done;
 	
 	spin_lock_irq(&hostdata->lock);
@@ -812,23 +805,20 @@ static void NCR5380_main(struct work_str
 			 * Search through the issue_queue for a command destined
 			 * for a target that's not busy.
 			 */
-			for (tmp = (struct scsi_cmnd *) hostdata->issue_queue, prev = NULL; tmp; prev = tmp, tmp = (struct scsi_cmnd *) tmp->host_scribble)
-			{
+			list_for_each_entry_safe(ncmd, n, &hostdata->unissued,
+			                         list) {
+				struct scsi_cmnd *tmp = NCR5380_to_scmd(ncmd);
+
 				dsprintk(NDEBUG_QUEUES, instance, "main: tmp=%p target=%d busy=%d lun=%llu\n",
 				         tmp, scmd_id(tmp), hostdata->busy[scmd_id(tmp)],
 				         tmp->device->lun);
 				/*  When we find one, remove it from the issue queue. */
 				if (!(hostdata->busy[tmp->device->id] &
 				      (1 << (u8)(tmp->device->lun & 0xff)))) {
-					if (prev) {
-						prev->host_scribble = tmp->host_scribble;
-					} else {
-						hostdata->issue_queue = (struct scsi_cmnd *) tmp->host_scribble;
-					}
-					tmp->host_scribble = NULL;
+					list_del(&ncmd->list);
 					dsprintk(NDEBUG_MAIN | NDEBUG_QUEUES,
-					         instance, "main: removed %p from issue queue %p\n",
-					         tmp, prev);
+					         instance, "main: removed %p from issue queue\n",
+					         tmp);
 
 					/* 
 					 * Attempt to establish an I_T_L nexus here. 
@@ -847,8 +837,7 @@ static void NCR5380_main(struct work_str
 						/* OK or bad target */
 					} else {
 						/* Need to retry */
-						tmp->host_scribble = (unsigned char *) hostdata->issue_queue;
-						hostdata->issue_queue = tmp;
+						list_add(&ncmd->list, &hostdata->unissued);
 						dsprintk(NDEBUG_MAIN | NDEBUG_QUEUES,
 						         instance, "main: select() failed, %p returned to issue queue\n",
 						         tmp);
@@ -1751,6 +1740,8 @@ static void NCR5380_information_transfer
 	struct scsi_cmnd *cmd;
 
 	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) {
@@ -1882,9 +1873,7 @@ static void NCR5380_information_transfer
 					if ((cmd->cmnd[0] != REQUEST_SENSE) && (status_byte(cmd->SCp.Status) == CHECK_CONDITION)) {
 						scsi_eh_prep_cmnd(cmd, &hostdata->ses, NULL, 0, ~0);
 
-						cmd->host_scribble = (unsigned char *)
-						    hostdata->issue_queue;
-						hostdata->issue_queue = (struct scsi_cmnd *) cmd;
+						list_add(&ncmd->list, &hostdata->unissued);
 						dsprintk(NDEBUG_AUTOSENSE | NDEBUG_QUEUES,
 						         instance, "REQUEST SENSE cmd %p added to head of issue queue\n",
 						         cmd);
@@ -1918,10 +1907,8 @@ static void NCR5380_information_transfer
 				case DISCONNECT:{
 						/* Accept message by clearing ACK */
 						NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
-						cmd->host_scribble = (unsigned char *)
-						    hostdata->disconnected_queue;
 						hostdata->connected = NULL;
-						hostdata->disconnected_queue = cmd;
+						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);
@@ -2094,7 +2081,8 @@ static void NCR5380_reselect(struct Scsi
 	int len;
 	unsigned char msg[3];
 	unsigned char *data;
-	struct scsi_cmnd *tmp = NULL, *prev;
+	struct NCR5380_cmd *ncmd;
+	struct scsi_cmnd *tmp;
 
 	/*
 	 * Disable arbitration, etc. since the host adapter obviously
@@ -2163,16 +2151,14 @@ static void NCR5380_reselect(struct Scsi
 	 * just reestablished, and remove it from the disconnected queue.
 	 */
 
-	for (tmp = (struct scsi_cmnd *) hostdata->disconnected_queue, prev = NULL;
-	     tmp; prev = tmp, tmp = (struct scsi_cmnd *) tmp->host_scribble) {
-		if ((target_mask == (1 << tmp->device->id)) && (lun == (u8)tmp->device->lun)) {
-			if (prev) {
-				prev->host_scribble = tmp->host_scribble;
-			} else {
-				hostdata->disconnected_queue =
-					(struct scsi_cmnd *) tmp->host_scribble;
-			}
-			tmp->host_scribble = NULL;
+	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) {
+			list_del(&ncmd->list);
+			tmp = cmd;
 			break;
 		}
 	}
@@ -2268,146 +2254,18 @@ static int NCR5380_abort(struct scsi_cmn
 {
 	struct Scsi_Host *instance = cmd->device->host;
 	struct NCR5380_hostdata *hostdata = shost_priv(instance);
-	struct scsi_cmnd *tmp, **prev;
 	unsigned long flags;
 
-	scmd_printk(KERN_WARNING, cmd, "aborting command\n");
-
 	spin_lock_irqsave(&hostdata->lock, flags);
 
+#if (NDEBUG & NDEBUG_ANY)
+	scmd_printk(KERN_INFO, cmd, "aborting command\n");
+#endif
 	NCR5380_dprint(NDEBUG_ANY, instance);
 	NCR5380_dprint_phase(NDEBUG_ANY, instance);
 
-	dprintk(NDEBUG_ABORT, "scsi%d : abort called\n", instance->host_no);
-	dprintk(NDEBUG_ABORT, "        basr 0x%X, sr 0x%X\n", NCR5380_read(BUS_AND_STATUS_REG), NCR5380_read(STATUS_REG));
-
-#if 0
-/*
- * Case 1 : If the command is the currently executing command, 
- * we'll set the aborted flag and return control so that 
- * information transfer routine can exit cleanly.
- */
-
-	if (hostdata->connected == cmd) {
-		dprintk(NDEBUG_ABORT, "scsi%d : aborting connected command\n", instance->host_no);
-/*
- * We should perform BSY checking, and make sure we haven't slipped
- * into BUS FREE.
- */
-
-		NCR5380_write(INITIATOR_COMMAND_REG, ICR_ASSERT_ATN);
-/* 
- * Since we can't change phases until we've completed the current 
- * handshake, we have to source or sink a byte of data if the current
- * phase is not MSGOUT.
- */
-
-/* 
- * Return control to the executing NCR drive so we can clear the
- * aborted flag and get back into our main loop.
- */
-
-		return SUCCESS;
-	}
-#endif
-
-/* 
- * Case 2 : If the command hasn't been issued yet, we simply remove it 
- *          from the issue queue.
- */
- 
-	dprintk(NDEBUG_ABORT, "scsi%d : abort going into loop.\n", instance->host_no);
-	for (prev = (struct scsi_cmnd **) &(hostdata->issue_queue), tmp = (struct scsi_cmnd *) hostdata->issue_queue; tmp; prev = (struct scsi_cmnd **) &(tmp->host_scribble), tmp = (struct scsi_cmnd *) tmp->host_scribble)
-		if (cmd == tmp) {
-			(*prev) = (struct scsi_cmnd *) tmp->host_scribble;
-			tmp->host_scribble = NULL;
-			spin_unlock_irqrestore(&hostdata->lock, flags);
-			tmp->result = DID_ABORT << 16;
-			dprintk(NDEBUG_ABORT, "scsi%d : abort removed command from issue queue.\n", instance->host_no);
-			tmp->scsi_done(tmp);
-			return SUCCESS;
-		}
-#if (NDEBUG  & NDEBUG_ABORT)
-	/* KLL */
-		else if (prev == tmp)
-			printk(KERN_ERR "scsi%d : LOOP\n", instance->host_no);
-#endif
-
-/* 
- * Case 3 : If any commands are connected, we're going to fail the abort
- *          and let the high level SCSI driver retry at a later time or 
- *          issue a reset.
- *
- *          Timeouts, and therefore aborted commands, will be highly unlikely
- *          and handling them cleanly in this situation would make the common
- *          case of noresets less efficient, and would pollute our code.  So,
- *          we fail.
- */
-
-	if (hostdata->connected) {
-		spin_unlock_irqrestore(&hostdata->lock, flags);
-		dprintk(NDEBUG_ABORT, "scsi%d : abort failed, command connected.\n", instance->host_no);
-		return FAILED;
-	}
-/*
- * Case 4: If the command is currently disconnected from the bus, and 
- *      there are no connected commands, we reconnect the I_T_L or 
- *      I_T_L_Q nexus associated with it, go into message out, and send 
- *      an abort message.
- *
- * This case is especially ugly. In order to reestablish the nexus, we
- * need to call NCR5380_select().  The easiest way to implement this 
- * function was to abort if the bus was busy, and let the interrupt
- * handler triggered on the SEL for reselect take care of lost arbitrations
- * where necessary, meaning interrupts need to be enabled.
- *
- * When interrupts are enabled, the queues may change - so we 
- * can't remove it from the disconnected queue before selecting it
- * because that could cause a failure in hashing the nexus if that 
- * device reselected.
- * 
- * Since the queues may change, we can't use the pointers from when we
- * first locate it.
- *
- * So, we must first locate the command, and if NCR5380_select()
- * succeeds, then issue the abort, relocate the command and remove
- * it from the disconnected queue.
- */
-
-	for (tmp = (struct scsi_cmnd *) hostdata->disconnected_queue; tmp; tmp = (struct scsi_cmnd *) tmp->host_scribble)
-		if (cmd == tmp) {
-			dprintk(NDEBUG_ABORT, "scsi%d : aborting disconnected command.\n", instance->host_no);
-
-			if (NCR5380_select(instance, cmd)) {
-				spin_unlock_irq(&hostdata->lock);
-				return FAILED;
-			}
-			dprintk(NDEBUG_ABORT, "scsi%d : nexus reestablished.\n", instance->host_no);
-
-			do_abort(instance);
-
-			for (prev = (struct scsi_cmnd **) &(hostdata->disconnected_queue), tmp = (struct scsi_cmnd *) hostdata->disconnected_queue; tmp; prev = (struct scsi_cmnd **) &(tmp->host_scribble), tmp = (struct scsi_cmnd *) tmp->host_scribble)
-				if (cmd == tmp) {
-					*prev = (struct scsi_cmnd *) tmp->host_scribble;
-					tmp->host_scribble = NULL;
-					spin_unlock_irqrestore(&hostdata->lock, flags);
-					tmp->result = DID_ABORT << 16;
-					tmp->scsi_done(tmp);
-					return SUCCESS;
-				}
-		}
-/*
- * Case 5 : If we reached this point, the command was not found in any of 
- *          the queues.
- *
- * We probably reached this point because of an unlikely race condition
- * between the command completing successfully and the abortion code,
- * so we won't panic, but we will notify the user in case something really
- * broke.
- */
 	spin_unlock_irqrestore(&hostdata->lock, flags);
-	printk(KERN_WARNING "scsi%d : warning : SCSI command probably completed successfully\n"
-			"         before abortion\n", instance->host_no);
+
 	return FAILED;
 }
 
Index: linux/drivers/scsi/atari_NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/atari_NCR5380.c	2015-11-18 19:34:19.000000000 +1100
+++ linux/drivers/scsi/atari_NCR5380.c	2015-11-18 19:34:20.000000000 +1100
@@ -175,10 +175,6 @@
  * possible) function may be used.
  */
 
-#define	NEXT(cmd)		((struct scsi_cmnd *)(cmd)->host_scribble)
-#define	SET_NEXT(cmd,next)	((cmd)->host_scribble = (void *)(next))
-#define	NEXTADDR(cmd)		((struct scsi_cmnd **)&(cmd)->host_scribble)
-
 #define	HOSTNO		instance->host_no
 
 static int do_abort(struct Scsi_Host *);
@@ -676,8 +672,9 @@ static int __init NCR5380_init(struct Sc
 #endif
 	spin_lock_init(&hostdata->lock);
 	hostdata->connected = NULL;
-	hostdata->issue_queue = NULL;
-	hostdata->disconnected_queue = NULL;
+	INIT_LIST_HEAD(&hostdata->unissued);
+	INIT_LIST_HEAD(&hostdata->disconnected);
+
 	hostdata->flags = flags;
 
 	INIT_WORK(&hostdata->main_task, NCR5380_main);
@@ -778,7 +775,7 @@ static int NCR5380_queue_command(struct
                                  struct scsi_cmnd *cmd)
 {
 	struct NCR5380_hostdata *hostdata = shost_priv(instance);
-	struct scsi_cmnd *tmp;
+	struct NCR5380_cmd *ncmd = scsi_cmd_priv(cmd);
 	unsigned long flags;
 
 #if (NDEBUG & NDEBUG_NO_WRITE)
@@ -792,12 +789,6 @@ static int NCR5380_queue_command(struct
 	}
 #endif /* (NDEBUG & NDEBUG_NO_WRITE) */
 
-	/*
-	 * We use the host_scribble field as a pointer to the next command
-	 * in a queue
-	 */
-
-	SET_NEXT(cmd, NULL);
 	cmd->result = 0;
 
 	/*
@@ -831,15 +822,11 @@ static int NCR5380_queue_command(struct
 	 * sense data is only guaranteed to be valid while the condition exists.
 	 */
 
-	if (!(hostdata->issue_queue) || (cmd->cmnd[0] == REQUEST_SENSE)) {
-		SET_NEXT(cmd, hostdata->issue_queue);
-		hostdata->issue_queue = cmd;
-	} else {
-		for (tmp = (struct scsi_cmnd *)hostdata->issue_queue;
-		     NEXT(tmp); tmp = NEXT(tmp))
-			;
-		SET_NEXT(tmp, cmd);
-	}
+	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",
@@ -855,8 +842,8 @@ static inline void maybe_release_dma_irq
 	struct NCR5380_hostdata *hostdata = shost_priv(instance);
 
 	/* Caller does the locking needed to set & test these data atomically */
-	if (!hostdata->disconnected_queue &&
-	    !hostdata->issue_queue &&
+	if (list_empty(&hostdata->disconnected) &&
+	    list_empty(&hostdata->unissued) &&
 	    !hostdata->connected &&
 	    !hostdata->retain_dma_intr)
 		NCR5380_release_dma_irq(instance);
@@ -878,7 +865,7 @@ static void NCR5380_main(struct work_str
 	struct NCR5380_hostdata *hostdata =
 		container_of(work, struct NCR5380_hostdata, main_task);
 	struct Scsi_Host *instance = hostdata->host;
-	struct scsi_cmnd *tmp, *prev;
+	struct NCR5380_cmd *ncmd, *n;
 	int done;
 
 	/*
@@ -897,17 +884,9 @@ static void NCR5380_main(struct work_str
 			 * Search through the issue_queue for a command destined
 			 * for a target that's not busy.
 			 */
-#if (NDEBUG & NDEBUG_LISTS)
-			for (tmp = (struct scsi_cmnd *) hostdata->issue_queue, prev = NULL;
-			     tmp && (tmp != prev); prev = tmp, tmp = NEXT(tmp))
-				;
-			/*printk("%p  ", tmp);*/
-			if ((tmp == prev) && tmp)
-				printk(" LOOP\n");
-			/* else printk("\n"); */
-#endif
-			for (tmp = (struct scsi_cmnd *) hostdata->issue_queue,
-			     prev = NULL; tmp; prev = tmp, tmp = NEXT(tmp)) {
+			list_for_each_entry_safe(ncmd, n, &hostdata->unissued,
+			                         list) {
+				struct scsi_cmnd *tmp = NCR5380_to_scmd(ncmd);
 				u8 lun = tmp->device->lun;
 
 				dsprintk(NDEBUG_QUEUES, instance, "main: tmp=%p target=%d busy=%d lun=%d\n",
@@ -920,15 +899,10 @@ static void NCR5380_main(struct work_str
 				    !(hostdata->busy[tmp->device->id] & (1 << lun))
 #endif
 				    ) {
-					if (prev) {
-						SET_NEXT(prev, NEXT(tmp));
-					} else {
-						hostdata->issue_queue = NEXT(tmp);
-					}
-					SET_NEXT(tmp, NULL);
+					list_del(&ncmd->list);
 					dsprintk(NDEBUG_MAIN | NDEBUG_QUEUES,
-					         instance, "main: removed %p from issue queue %p\n",
-					         tmp, prev);
+					         instance, "main: removed %p from issue queue\n",
+					         tmp);
 
 					hostdata->retain_dma_intr++;
 
@@ -957,8 +931,7 @@ static void NCR5380_main(struct work_str
 						maybe_release_dma_irq(instance);
 					} else {
 						/* Need to retry */
-						SET_NEXT(tmp, hostdata->issue_queue);
-						hostdata->issue_queue = tmp;
+						list_add(&ncmd->list, &hostdata->unissued);
 						dsprintk(NDEBUG_MAIN | NDEBUG_QUEUES,
 						         instance, "main: select() failed, %p returned to issue queue\n",
 						         tmp);
@@ -1843,6 +1816,8 @@ static void NCR5380_information_transfer
 #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) {
@@ -2051,8 +2026,7 @@ static void NCR5380_information_transfer
 					    (status_byte(cmd->SCp.Status) == CHECK_CONDITION)) {
 						scsi_eh_prep_cmnd(cmd, &hostdata->ses, NULL, 0, ~0);
 
-						SET_NEXT(cmd, hostdata->issue_queue);
-						hostdata->issue_queue = (struct scsi_cmnd *) cmd;
+						list_add(&ncmd->list, &hostdata->unissued);
 						dsprintk(NDEBUG_AUTOSENSE | NDEBUG_QUEUES,
 						         instance, "REQUEST SENSE cmd %p added to head of issue queue\n",
 						         cmd);
@@ -2101,9 +2075,8 @@ static void NCR5380_information_transfer
 				case DISCONNECT:
 					/* Accept message by clearing ACK */
 					NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
-					SET_NEXT(cmd, hostdata->disconnected_queue);
 					hostdata->connected = NULL;
-					hostdata->disconnected_queue = cmd;
+					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);
@@ -2297,7 +2270,8 @@ static void NCR5380_reselect(struct Scsi
 	unsigned char msg[3];
 	int __maybe_unused len;
 	unsigned char __maybe_unused *data, __maybe_unused phase;
-	struct scsi_cmnd *tmp = NULL, *prev;
+	struct NCR5380_cmd *ncmd;
+	struct scsi_cmnd *tmp;
 
 	/*
 	 * Disable arbitration, etc. since the host adapter obviously
@@ -2388,19 +2362,18 @@ static void NCR5380_reselect(struct Scsi
 	 * just reestablished, and remove it from the disconnected queue.
 	 */
 
-	for (tmp = (struct scsi_cmnd *) hostdata->disconnected_queue, prev = NULL;
-	     tmp; prev = tmp, tmp = NEXT(tmp)) {
-		if ((target_mask == (1 << tmp->device->id)) && (lun == (u8)tmp->device->lun)
+	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 == tmp->tag)
 #endif
 		    ) {
-			if (prev) {
-				SET_NEXT(prev, NEXT(tmp));
-			} else {
-				hostdata->disconnected_queue = NEXT(tmp);
-			}
-			SET_NEXT(tmp, NULL);
+			list_del(&ncmd->list);
+			tmp = cmd;
 			break;
 		}
 	}
@@ -2498,188 +2471,18 @@ int NCR5380_abort(struct scsi_cmnd *cmd)
 {
 	struct Scsi_Host *instance = cmd->device->host;
 	struct NCR5380_hostdata *hostdata = shost_priv(instance);
-	struct scsi_cmnd *tmp, **prev;
 	unsigned long flags;
 
-	scmd_printk(KERN_NOTICE, cmd, "aborting command\n");
-
 	spin_lock_irqsave(&hostdata->lock, flags);
 
+#if (NDEBUG & NDEBUG_ANY)
+	scmd_printk(KERN_INFO, cmd, "aborting command\n");
+#endif
 	NCR5380_dprint(NDEBUG_ANY, instance);
 	NCR5380_dprint_phase(NDEBUG_ANY, instance);
 
-	dprintk(NDEBUG_ABORT, "scsi%d: abort called basr 0x%02x, sr 0x%02x\n", HOSTNO,
-		    NCR5380_read(BUS_AND_STATUS_REG),
-		    NCR5380_read(STATUS_REG));
-
-#if 1
-	/*
-	 * Case 1 : If the command is the currently executing command,
-	 * we'll set the aborted flag and return control so that
-	 * information transfer routine can exit cleanly.
-	 */
-
-	if (hostdata->connected == cmd) {
-
-		dprintk(NDEBUG_ABORT, "scsi%d: aborting connected command\n", HOSTNO);
-		/*
-		 * We should perform BSY checking, and make sure we haven't slipped
-		 * into BUS FREE.
-		 */
-
-		/*	NCR5380_write(INITIATOR_COMMAND_REG, ICR_ASSERT_ATN); */
-		/*
-		 * Since we can't change phases until we've completed the current
-		 * handshake, we have to source or sink a byte of data if the current
-		 * phase is not MSGOUT.
-		 */
-
-		/*
-		 * Return control to the executing NCR drive so we can clear the
-		 * aborted flag and get back into our main loop.
-		 */
-
-		if (do_abort(instance) == 0) {
-			hostdata->connected = NULL;
-			cmd->result = DID_ABORT << 16;
-#ifdef SUPPORT_TAGS
-			cmd_free_tag(cmd);
-#else
-			hostdata->busy[cmd->device->id] &= ~(1 << cmd->device->lun);
-#endif
-			maybe_release_dma_irq(instance);
-			spin_unlock_irqrestore(&hostdata->lock, flags);
-			cmd->scsi_done(cmd);
-			return SUCCESS;
-		} else {
-			spin_unlock_irqrestore(&hostdata->lock, flags);
-			printk("scsi%d: abort of connected command failed!\n", HOSTNO);
-			return FAILED;
-		}
-	}
-#endif
-
-	/*
-	 * Case 2 : If the command hasn't been issued yet, we simply remove it
-	 *	    from the issue queue.
-	 */
-	for (prev = (struct scsi_cmnd **)&(hostdata->issue_queue),
-	     tmp = (struct scsi_cmnd *)hostdata->issue_queue;
-	     tmp; prev = NEXTADDR(tmp), tmp = NEXT(tmp)) {
-		if (cmd == tmp) {
-			(*prev) = NEXT(tmp);
-			SET_NEXT(tmp, NULL);
-			tmp->result = DID_ABORT << 16;
-			maybe_release_dma_irq(instance);
-			spin_unlock_irqrestore(&hostdata->lock, flags);
-			dprintk(NDEBUG_ABORT, "scsi%d: abort removed command from issue queue.\n",
-				    HOSTNO);
-			/* Tagged queuing note: no tag to free here, hasn't been assigned
-			 * yet... */
-			tmp->scsi_done(tmp);
-			return SUCCESS;
-		}
-	}
-
-	/*
-	 * Case 3 : If any commands are connected, we're going to fail the abort
-	 *	    and let the high level SCSI driver retry at a later time or
-	 *	    issue a reset.
-	 *
-	 *	    Timeouts, and therefore aborted commands, will be highly unlikely
-	 *          and handling them cleanly in this situation would make the common
-	 *	    case of noresets less efficient, and would pollute our code.  So,
-	 *	    we fail.
-	 */
-
-	if (hostdata->connected) {
-		spin_unlock_irqrestore(&hostdata->lock, flags);
-		dprintk(NDEBUG_ABORT, "scsi%d: abort failed, command connected.\n", HOSTNO);
-		return FAILED;
-	}
-
-	/*
-	 * Case 4: If the command is currently disconnected from the bus, and
-	 *	there are no connected commands, we reconnect the I_T_L or
-	 *	I_T_L_Q nexus associated with it, go into message out, and send
-	 *      an abort message.
-	 *
-	 * This case is especially ugly. In order to reestablish the nexus, we
-	 * need to call NCR5380_select().  The easiest way to implement this
-	 * function was to abort if the bus was busy, and let the interrupt
-	 * handler triggered on the SEL for reselect take care of lost arbitrations
-	 * where necessary, meaning interrupts need to be enabled.
-	 *
-	 * When interrupts are enabled, the queues may change - so we
-	 * can't remove it from the disconnected queue before selecting it
-	 * because that could cause a failure in hashing the nexus if that
-	 * device reselected.
-	 *
-	 * Since the queues may change, we can't use the pointers from when we
-	 * first locate it.
-	 *
-	 * So, we must first locate the command, and if NCR5380_select()
-	 * succeeds, then issue the abort, relocate the command and remove
-	 * it from the disconnected queue.
-	 */
-
-	for (tmp = (struct scsi_cmnd *) hostdata->disconnected_queue; tmp;
-	     tmp = NEXT(tmp)) {
-		if (cmd == tmp) {
-			dprintk(NDEBUG_ABORT, "scsi%d: aborting disconnected command.\n", HOSTNO);
-
-			if (NCR5380_select(instance, cmd)) {
-				spin_unlock_irq(&hostdata->lock);
-				return FAILED;
-			}
-			dprintk(NDEBUG_ABORT, "scsi%d: nexus reestablished.\n", HOSTNO);
-
-			do_abort(instance);
-
-			for (prev = (struct scsi_cmnd **)&(hostdata->disconnected_queue),
-			     tmp = (struct scsi_cmnd *)hostdata->disconnected_queue;
-			     tmp; prev = NEXTADDR(tmp), tmp = NEXT(tmp)) {
-				if (cmd == tmp) {
-					*prev = NEXT(tmp);
-					SET_NEXT(tmp, NULL);
-					tmp->result = DID_ABORT << 16;
-					/* We must unlock the tag/LUN immediately here, since the
-					 * target goes to BUS FREE and doesn't send us another
-					 * message (COMMAND_COMPLETE or the like)
-					 */
-#ifdef SUPPORT_TAGS
-					cmd_free_tag(tmp);
-#else
-					hostdata->busy[cmd->device->id] &= ~(1 << cmd->device->lun);
-#endif
-					maybe_release_dma_irq(instance);
-					spin_unlock_irqrestore(&hostdata->lock, flags);
-					tmp->scsi_done(tmp);
-					return SUCCESS;
-				}
-			}
-		}
-	}
-
-	/* Maybe it is sufficient just to release the ST-DMA lock... (if
-	 * possible at all) At least, we should check if the lock could be
-	 * released after the abort, in case it is kept due to some bug.
-	 */
-	maybe_release_dma_irq(instance);
 	spin_unlock_irqrestore(&hostdata->lock, flags);
 
-	/*
-	 * Case 5 : If we reached this point, the command was not found in any of
-	 *	    the queues.
-	 *
-	 * We probably reached this point because of an unlikely race condition
-	 * between the command completing successfully and the abortion code,
-	 * so we won't panic, but we will notify the user in case something really
-	 * broke.
-	 */
-
-	printk(KERN_INFO "scsi%d: warning : SCSI command probably completed successfully before abortion\n", HOSTNO);
-
 	return FAILED;
 }
 
@@ -2719,16 +2522,18 @@ static int NCR5380_bus_reset(struct scsi
 	 * commands!
 	 */
 
-	if (hostdata->issue_queue)
-		dsprintk(NDEBUG_ABORT, instance, "reset aborted issued command(s)\n");
 	if (hostdata->connected)
 		dsprintk(NDEBUG_ABORT, instance, "reset aborted a connected command\n");
-	if (hostdata->disconnected_queue)
-		dsprintk(NDEBUG_ABORT, instance, "reset aborted disconnected command(s)\n");
-
-	hostdata->issue_queue = NULL;
 	hostdata->connected = NULL;
-	hostdata->disconnected_queue = NULL;
+
+	if (!list_empty(&hostdata->unissued))
+		dsprintk(NDEBUG_ABORT, instance, "reset aborted unissued list\n");
+	INIT_LIST_HEAD(&hostdata->unissued);
+
+	if (!list_empty(&hostdata->disconnected))
+		dsprintk(NDEBUG_ABORT, instance, "reset aborted disconnected list\n");
+	INIT_LIST_HEAD(&hostdata->disconnected);
+
 #ifdef SUPPORT_TAGS
 	free_all_tags(hostdata);
 #endif
Index: linux/drivers/scsi/NCR5380.h
===================================================================
--- linux.orig/drivers/scsi/NCR5380.h	2015-11-18 19:34:19.000000000 +1100
+++ linux/drivers/scsi/NCR5380.h	2015-11-18 19:34:20.000000000 +1100
@@ -24,6 +24,7 @@
 
 #include <linux/delay.h>
 #include <linux/interrupt.h>
+#include <linux/list.h>
 #include <linux/workqueue.h>
 #include <scsi/scsi_dbg.h>
 #include <scsi/scsi_eh.h>
@@ -255,8 +256,8 @@ struct NCR5380_hostdata {
 #endif
 	unsigned char last_message;		/* last message OUT */
 	struct scsi_cmnd *connected;		/* currently connected cmnd */
-	struct scsi_cmnd *issue_queue;		/* waiting to be issued */
-	struct scsi_cmnd *disconnected_queue;	/* waiting for reconnect */
+	struct list_head unissued;		/* waiting to be issued */
+	struct list_head disconnected;		/* waiting for reconnect */
 	spinlock_t lock;			/* protects this struct */
 	int flags;
 	struct scsi_eh_save ses;
@@ -277,6 +278,17 @@ struct NCR5380_hostdata {
 
 #ifdef __KERNEL__
 
+struct NCR5380_cmd {
+	struct list_head list;
+};
+
+#define NCR5380_CMD_SIZE		(sizeof(struct NCR5380_cmd))
+
+static inline struct scsi_cmnd *NCR5380_to_scmd(struct NCR5380_cmd *ncmd_ptr)
+{
+	return ((struct scsi_cmnd *)ncmd_ptr) - 1;
+}
+
 #ifndef NDEBUG
 #define NDEBUG (0)
 #endif
Index: linux/drivers/scsi/arm/cumana_1.c
===================================================================
--- linux.orig/drivers/scsi/arm/cumana_1.c	2015-11-18 19:34:01.000000000 +1100
+++ linux/drivers/scsi/arm/cumana_1.c	2015-11-18 19:34:20.000000000 +1100
@@ -208,6 +208,7 @@ static struct scsi_host_template cumanas
 	.cmd_per_lun		= 2,
 	.use_clustering		= DISABLE_CLUSTERING,
 	.proc_name		= "CumanaSCSI-1",
+	.cmd_size		= NCR5380_CMD_SIZE,
 };
 
 static int cumanascsi1_probe(struct expansion_card *ec,
Index: linux/drivers/scsi/arm/oak.c
===================================================================
--- linux.orig/drivers/scsi/arm/oak.c	2015-11-18 19:34:12.000000000 +1100
+++ linux/drivers/scsi/arm/oak.c	2015-11-18 19:34:20.000000000 +1100
@@ -114,6 +114,7 @@ static struct scsi_host_template oakscsi
 	.cmd_per_lun		= 2,
 	.use_clustering		= DISABLE_CLUSTERING,
 	.proc_name		= "oakscsi",
+	.cmd_size		= NCR5380_CMD_SIZE,
 };
 
 static int oakscsi_probe(struct expansion_card *ec, const struct ecard_id *id)
Index: linux/drivers/scsi/atari_scsi.c
===================================================================
--- linux.orig/drivers/scsi/atari_scsi.c	2015-11-18 19:34:12.000000000 +1100
+++ linux/drivers/scsi/atari_scsi.c	2015-11-18 19:34:20.000000000 +1100
@@ -780,6 +780,7 @@ static struct scsi_host_template atari_s
 	.eh_bus_reset_handler	= atari_scsi_bus_reset,
 	.this_id		= 7,
 	.use_clustering		= DISABLE_CLUSTERING,
+	.cmd_size		= NCR5380_CMD_SIZE,
 };
 
 static int __init atari_scsi_probe(struct platform_device *pdev)
Index: linux/drivers/scsi/dmx3191d.c
===================================================================
--- linux.orig/drivers/scsi/dmx3191d.c	2015-11-18 19:34:05.000000000 +1100
+++ linux/drivers/scsi/dmx3191d.c	2015-11-18 19:34:20.000000000 +1100
@@ -61,6 +61,7 @@ static struct scsi_host_template dmx3191
 	.sg_tablesize		= SG_ALL,
 	.cmd_per_lun		= 2,
 	.use_clustering		= DISABLE_CLUSTERING,
+	.cmd_size		= NCR5380_CMD_SIZE,
 };
 
 static int dmx3191d_probe_one(struct pci_dev *pdev,
Index: linux/drivers/scsi/dtc.c
===================================================================
--- linux.orig/drivers/scsi/dtc.c	2015-11-18 19:34:05.000000000 +1100
+++ linux/drivers/scsi/dtc.c	2015-11-18 19:34:20.000000000 +1100
@@ -452,5 +452,6 @@ static struct scsi_host_template driver_
 	.sg_tablesize		= SG_ALL,
 	.cmd_per_lun		= 2,
 	.use_clustering		= DISABLE_CLUSTERING,
+	.cmd_size		= NCR5380_CMD_SIZE,
 };
 #include "scsi_module.c"
Index: linux/drivers/scsi/g_NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/g_NCR5380.c	2015-11-18 19:34:12.000000000 +1100
+++ linux/drivers/scsi/g_NCR5380.c	2015-11-18 19:34:20.000000000 +1100
@@ -729,6 +729,7 @@ static struct scsi_host_template driver_
 	.sg_tablesize		= SG_ALL,
 	.cmd_per_lun		= 2,
 	.use_clustering		= DISABLE_CLUSTERING,
+	.cmd_size		= NCR5380_CMD_SIZE,
 };
 
 #include "scsi_module.c"
Index: linux/drivers/scsi/mac_scsi.c
===================================================================
--- linux.orig/drivers/scsi/mac_scsi.c	2015-11-18 19:34:05.000000000 +1100
+++ linux/drivers/scsi/mac_scsi.c	2015-11-18 19:34:20.000000000 +1100
@@ -323,6 +323,7 @@ static struct scsi_host_template mac_scs
 	.sg_tablesize		= SG_ALL,
 	.cmd_per_lun		= 2,
 	.use_clustering		= DISABLE_CLUSTERING,
+	.cmd_size		= NCR5380_CMD_SIZE,
 };
 
 static int __init mac_scsi_probe(struct platform_device *pdev)
Index: linux/drivers/scsi/pas16.c
===================================================================
--- linux.orig/drivers/scsi/pas16.c	2015-11-18 19:34:05.000000000 +1100
+++ linux/drivers/scsi/pas16.c	2015-11-18 19:34:20.000000000 +1100
@@ -562,6 +562,7 @@ static struct scsi_host_template driver_
 	.sg_tablesize		= SG_ALL,
 	.cmd_per_lun		= 2,
 	.use_clustering		= DISABLE_CLUSTERING,
+	.cmd_size		= NCR5380_CMD_SIZE,
 };
 #include "scsi_module.c"
 
Index: linux/drivers/scsi/sun3_scsi.c
===================================================================
--- linux.orig/drivers/scsi/sun3_scsi.c	2015-11-18 19:34:12.000000000 +1100
+++ linux/drivers/scsi/sun3_scsi.c	2015-11-18 19:34:20.000000000 +1100
@@ -468,6 +468,7 @@ static struct scsi_host_template sun3_sc
 	.sg_tablesize		= SG_NONE,
 	.cmd_per_lun		= 2,
 	.use_clustering		= DISABLE_CLUSTERING,
+	.cmd_size		= NCR5380_CMD_SIZE,
 };
 
 static int __init sun3_scsi_probe(struct platform_device *pdev)
Index: linux/drivers/scsi/t128.c
===================================================================
--- linux.orig/drivers/scsi/t128.c	2015-11-18 19:34:05.000000000 +1100
+++ linux/drivers/scsi/t128.c	2015-11-18 19:34:20.000000000 +1100
@@ -406,5 +406,6 @@ static struct scsi_host_template driver_
 	.sg_tablesize		= SG_ALL,
 	.cmd_per_lun		= 2,
 	.use_clustering		= DISABLE_CLUSTERING,
+	.cmd_size		= NCR5380_CMD_SIZE,
 };
 #include "scsi_module.c"

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

* [PATCH 57/71] ncr5380: Use standard list data structure
@ 2015-11-18  8:35   ` Finn Thain
  0 siblings, 0 replies; 268+ messages in thread
From: Finn Thain @ 2015-11-18  8:35 UTC (permalink / raw)
  To: linux-arm-kernel

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

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

* [PATCH 58/71] ncr5380: Refactor command completion
  2015-11-18  8:34 ` Finn Thain
@ 2015-11-18  8:35   ` Finn Thain
  -1 siblings, 0 replies; 268+ messages in thread
From: Finn Thain @ 2015-11-18  8:35 UTC (permalink / raw)
  To: James E.J. Bottomley, Michael Schmitz, linux-m68k, linux-scsi,
	linux-kernel

[-- Attachment #1: ncr5380-complete_cmd --]
[-- Type: text/plain, Size: 6781 bytes --]

Implement a 'complete_cmd' function to complete commands. This is needed
by the following patch; the new function provides a site for the logic
needed to correctly handle REQUEST SENSE commands.

Signed-off-by: Finn Thain <fthain@telegraphics.com.au>

---
 drivers/scsi/NCR5380.c       |   31 ++++++++++++++++++++++------
 drivers/scsi/atari_NCR5380.c |   46 ++++++++++++++++++++++++++++---------------
 2 files changed, 55 insertions(+), 22 deletions(-)

Index: linux/drivers/scsi/atari_NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/atari_NCR5380.c	2015-11-18 19:34:20.000000000 +1100
+++ linux/drivers/scsi/atari_NCR5380.c	2015-11-18 19:34:23.000000000 +1100
@@ -762,6 +762,27 @@ static void NCR5380_exit(struct Scsi_Hos
 }
 
 /**
+ * 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);
+
+#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
@@ -1361,10 +1382,7 @@ static int NCR5380_select(struct Scsi_Ho
 		spin_lock_irq(&hostdata->lock);
 		NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
 		cmd->result = DID_BAD_TARGET << 16;
-#ifdef SUPPORT_TAGS
-		cmd_free_tag(cmd);
-#endif
-		cmd->scsi_done(cmd);
+		complete_cmd(instance, cmd);
 		NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
 		dprintk(NDEBUG_SELECTION, "scsi%d: target did not respond within 250ms\n", HOSTNO);
 		return 0;
@@ -1875,7 +1893,7 @@ static void NCR5380_information_transfer
 				sink = 1;
 				do_abort(instance);
 				cmd->result = DID_ERROR << 16;
-				cmd->scsi_done(cmd);
+				complete_cmd(instance, cmd);
 				return;
 #endif
 			case PHASE_DATAIN:
@@ -1935,7 +1953,7 @@ static void NCR5380_information_transfer
 						sink = 1;
 						do_abort(instance);
 						cmd->result = DID_ERROR << 16;
-						cmd->scsi_done(cmd);
+						complete_cmd(instance, cmd);
 						/* XXX - need to source or sink data here, as appropriate */
 					} else {
 #ifdef REAL_DMA
@@ -1991,8 +2009,6 @@ static void NCR5380_information_transfer
 						if (ta->queue_size > ta->nr_allocated)
 							ta->queue_size = ta->nr_allocated;
 					}
-#else
-					hostdata->busy[cmd->device->id] &= ~(1 << cmd->device->lun);
 #endif
 
 					/*
@@ -2030,8 +2046,13 @@ static void NCR5380_information_transfer
 						dsprintk(NDEBUG_AUTOSENSE | NDEBUG_QUEUES,
 						         instance, "REQUEST SENSE cmd %p added to head of issue queue\n",
 						         cmd);
+#ifdef SUPPORT_TAGS
+						cmd_free_tag(cmd);
+#else
+						hostdata->busy[cmd->device->id] &= ~(1 << cmd->device->lun);
+#endif
 					} else {
-						cmd->scsi_done(cmd);
+						complete_cmd(instance, cmd);
 					}
 
 					/*
@@ -2202,15 +2223,10 @@ static void NCR5380_information_transfer
 				hostdata->last_message = msgout;
 				NCR5380_transfer_pio(instance, &phase, &len, &data);
 				if (msgout == ABORT) {
-#ifdef SUPPORT_TAGS
-					cmd_free_tag(cmd);
-#else
-					hostdata->busy[cmd->device->id] &= ~(1 << cmd->device->lun);
-#endif
 					hostdata->connected = NULL;
 					cmd->result = DID_ERROR << 16;
+					complete_cmd(instance, cmd);
 					maybe_release_dma_irq(instance);
-					cmd->scsi_done(cmd);
 					NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
 					return;
 				}
Index: linux/drivers/scsi/NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/NCR5380.c	2015-11-18 19:34:20.000000000 +1100
+++ linux/drivers/scsi/NCR5380.c	2015-11-18 19:34:23.000000000 +1100
@@ -722,6 +722,24 @@ static void NCR5380_exit(struct Scsi_Hos
 }
 
 /**
+ * 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);
+
+	hostdata->busy[scmd_id(cmd)] &= ~(1 << cmd->device->lun);
+
+	cmd->scsi_done(cmd);
+}
+
+/**
  * NCR5380_queue_command - queue a command
  * @instance: the relevant SCSI adapter
  * @cmd: SCSI command
@@ -1178,7 +1196,7 @@ static int NCR5380_select(struct Scsi_Ho
 		spin_lock_irq(&hostdata->lock);
 		NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
 		cmd->result = DID_BAD_TARGET << 16;
-		cmd->scsi_done(cmd);
+		complete_cmd(instance, cmd);
 		NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
 		dprintk(NDEBUG_SELECTION, "scsi%d : target did not respond within 250ms\n",
 		        instance->host_no);
@@ -1766,7 +1784,7 @@ static void NCR5380_information_transfer
 				sink = 1;
 				do_abort(instance);
 				cmd->result = DID_ERROR << 16;
-				cmd->scsi_done(cmd);
+				complete_cmd(instance, cmd);
 				return;
 #endif
 			case PHASE_DATAIN:
@@ -1811,7 +1829,7 @@ static void NCR5380_information_transfer
 						sink = 1;
 						do_abort(instance);
 						cmd->result = DID_ERROR << 16;
-						cmd->scsi_done(cmd);
+						complete_cmd(instance, cmd);
 						/* XXX - need to source or sink data here, as appropriate */
 					} else
 						cmd->SCp.this_residual -= transfersize - len;
@@ -1841,7 +1859,6 @@ static void NCR5380_information_transfer
 					         cmd, scmd_id(cmd), cmd->device->lun);
 
 					hostdata->connected = NULL;
-					hostdata->busy[cmd->device->id] &= ~(1 << (cmd->device->lun & 0xFF));
 
 					/* 
 					 * I'm not sure what the correct thing to do here is : 
@@ -1877,8 +1894,9 @@ static void NCR5380_information_transfer
 						dsprintk(NDEBUG_AUTOSENSE | NDEBUG_QUEUES,
 						         instance, "REQUEST SENSE cmd %p added to head of issue queue\n",
 						         cmd);
+						hostdata->busy[cmd->device->id] &= ~(1 << (cmd->device->lun & 0xFF));
 					} else {
-						cmd->scsi_done(cmd);
+						complete_cmd(instance, cmd);
 					}
 
 					/* 
@@ -2025,10 +2043,9 @@ static void NCR5380_information_transfer
 				hostdata->last_message = msgout;
 				NCR5380_transfer_pio(instance, &phase, &len, &data);
 				if (msgout == ABORT) {
-					hostdata->busy[cmd->device->id] &= ~(1 << (cmd->device->lun & 0xFF));
 					hostdata->connected = NULL;
 					cmd->result = DID_ERROR << 16;
-					cmd->scsi_done(cmd);
+					complete_cmd(instance, cmd);
 					NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
 					return;
 				}



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

* [PATCH 58/71] ncr5380: Refactor command completion
@ 2015-11-18  8:35   ` Finn Thain
  0 siblings, 0 replies; 268+ messages in thread
From: Finn Thain @ 2015-11-18  8:35 UTC (permalink / raw)
  To: James E.J. Bottomley, Michael Schmitz, linux-m68k, linux-scsi,
	linux-kernel

[-- Attachment #1: ncr5380-complete_cmd --]
[-- Type: text/plain, Size: 6779 bytes --]

Implement a 'complete_cmd' function to complete commands. This is needed
by the following patch; the new function provides a site for the logic
needed to correctly handle REQUEST SENSE commands.

Signed-off-by: Finn Thain <fthain@telegraphics.com.au>

---
 drivers/scsi/NCR5380.c       |   31 ++++++++++++++++++++++------
 drivers/scsi/atari_NCR5380.c |   46 ++++++++++++++++++++++++++++---------------
 2 files changed, 55 insertions(+), 22 deletions(-)

Index: linux/drivers/scsi/atari_NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/atari_NCR5380.c	2015-11-18 19:34:20.000000000 +1100
+++ linux/drivers/scsi/atari_NCR5380.c	2015-11-18 19:34:23.000000000 +1100
@@ -762,6 +762,27 @@ static void NCR5380_exit(struct Scsi_Hos
 }
 
 /**
+ * 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);
+
+#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
@@ -1361,10 +1382,7 @@ static int NCR5380_select(struct Scsi_Ho
 		spin_lock_irq(&hostdata->lock);
 		NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
 		cmd->result = DID_BAD_TARGET << 16;
-#ifdef SUPPORT_TAGS
-		cmd_free_tag(cmd);
-#endif
-		cmd->scsi_done(cmd);
+		complete_cmd(instance, cmd);
 		NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
 		dprintk(NDEBUG_SELECTION, "scsi%d: target did not respond within 250ms\n", HOSTNO);
 		return 0;
@@ -1875,7 +1893,7 @@ static void NCR5380_information_transfer
 				sink = 1;
 				do_abort(instance);
 				cmd->result = DID_ERROR << 16;
-				cmd->scsi_done(cmd);
+				complete_cmd(instance, cmd);
 				return;
 #endif
 			case PHASE_DATAIN:
@@ -1935,7 +1953,7 @@ static void NCR5380_information_transfer
 						sink = 1;
 						do_abort(instance);
 						cmd->result = DID_ERROR << 16;
-						cmd->scsi_done(cmd);
+						complete_cmd(instance, cmd);
 						/* XXX - need to source or sink data here, as appropriate */
 					} else {
 #ifdef REAL_DMA
@@ -1991,8 +2009,6 @@ static void NCR5380_information_transfer
 						if (ta->queue_size > ta->nr_allocated)
 							ta->queue_size = ta->nr_allocated;
 					}
-#else
-					hostdata->busy[cmd->device->id] &= ~(1 << cmd->device->lun);
 #endif
 
 					/*
@@ -2030,8 +2046,13 @@ static void NCR5380_information_transfer
 						dsprintk(NDEBUG_AUTOSENSE | NDEBUG_QUEUES,
 						         instance, "REQUEST SENSE cmd %p added to head of issue queue\n",
 						         cmd);
+#ifdef SUPPORT_TAGS
+						cmd_free_tag(cmd);
+#else
+						hostdata->busy[cmd->device->id] &= ~(1 << cmd->device->lun);
+#endif
 					} else {
-						cmd->scsi_done(cmd);
+						complete_cmd(instance, cmd);
 					}
 
 					/*
@@ -2202,15 +2223,10 @@ static void NCR5380_information_transfer
 				hostdata->last_message = msgout;
 				NCR5380_transfer_pio(instance, &phase, &len, &data);
 				if (msgout == ABORT) {
-#ifdef SUPPORT_TAGS
-					cmd_free_tag(cmd);
-#else
-					hostdata->busy[cmd->device->id] &= ~(1 << cmd->device->lun);
-#endif
 					hostdata->connected = NULL;
 					cmd->result = DID_ERROR << 16;
+					complete_cmd(instance, cmd);
 					maybe_release_dma_irq(instance);
-					cmd->scsi_done(cmd);
 					NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
 					return;
 				}
Index: linux/drivers/scsi/NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/NCR5380.c	2015-11-18 19:34:20.000000000 +1100
+++ linux/drivers/scsi/NCR5380.c	2015-11-18 19:34:23.000000000 +1100
@@ -722,6 +722,24 @@ static void NCR5380_exit(struct Scsi_Hos
 }
 
 /**
+ * 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);
+
+	hostdata->busy[scmd_id(cmd)] &= ~(1 << cmd->device->lun);
+
+	cmd->scsi_done(cmd);
+}
+
+/**
  * NCR5380_queue_command - queue a command
  * @instance: the relevant SCSI adapter
  * @cmd: SCSI command
@@ -1178,7 +1196,7 @@ static int NCR5380_select(struct Scsi_Ho
 		spin_lock_irq(&hostdata->lock);
 		NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
 		cmd->result = DID_BAD_TARGET << 16;
-		cmd->scsi_done(cmd);
+		complete_cmd(instance, cmd);
 		NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
 		dprintk(NDEBUG_SELECTION, "scsi%d : target did not respond within 250ms\n",
 		        instance->host_no);
@@ -1766,7 +1784,7 @@ static void NCR5380_information_transfer
 				sink = 1;
 				do_abort(instance);
 				cmd->result = DID_ERROR << 16;
-				cmd->scsi_done(cmd);
+				complete_cmd(instance, cmd);
 				return;
 #endif
 			case PHASE_DATAIN:
@@ -1811,7 +1829,7 @@ static void NCR5380_information_transfer
 						sink = 1;
 						do_abort(instance);
 						cmd->result = DID_ERROR << 16;
-						cmd->scsi_done(cmd);
+						complete_cmd(instance, cmd);
 						/* XXX - need to source or sink data here, as appropriate */
 					} else
 						cmd->SCp.this_residual -= transfersize - len;
@@ -1841,7 +1859,6 @@ static void NCR5380_information_transfer
 					         cmd, scmd_id(cmd), cmd->device->lun);
 
 					hostdata->connected = NULL;
-					hostdata->busy[cmd->device->id] &= ~(1 << (cmd->device->lun & 0xFF));
 
 					/* 
 					 * I'm not sure what the correct thing to do here is : 
@@ -1877,8 +1894,9 @@ static void NCR5380_information_transfer
 						dsprintk(NDEBUG_AUTOSENSE | NDEBUG_QUEUES,
 						         instance, "REQUEST SENSE cmd %p added to head of issue queue\n",
 						         cmd);
+						hostdata->busy[cmd->device->id] &= ~(1 << (cmd->device->lun & 0xFF));
 					} else {
-						cmd->scsi_done(cmd);
+						complete_cmd(instance, cmd);
 					}
 
 					/* 
@@ -2025,10 +2043,9 @@ static void NCR5380_information_transfer
 				hostdata->last_message = msgout;
 				NCR5380_transfer_pio(instance, &phase, &len, &data);
 				if (msgout == ABORT) {
-					hostdata->busy[cmd->device->id] &= ~(1 << (cmd->device->lun & 0xFF));
 					hostdata->connected = NULL;
 					cmd->result = DID_ERROR << 16;
-					cmd->scsi_done(cmd);
+					complete_cmd(instance, cmd);
 					NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
 					return;
 				}

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

* [PATCH 59/71] ncr5380: Fix autosense bugs
  2015-11-18  8:34 ` Finn Thain
@ 2015-11-18  8:35   ` Finn Thain
  -1 siblings, 0 replies; 268+ messages in thread
From: Finn Thain @ 2015-11-18  8:35 UTC (permalink / raw)
  To: James E.J. Bottomley, Michael Schmitz, linux-m68k, linux-scsi,
	linux-kernel

[-- Attachment #1: ncr5380-autosense-queue --]
[-- Type: text/plain, Size: 21555 bytes --]

NCR5380_information_transfer() may re-queue a command for autosense,
after calling scsi_eh_prep_cmnd(). This creates several possibilities:

1. Reselection may intervene before the re-queued command gets processed.
   If the reconnected command then undergoes autosense, this causes the
   scsi_eh_save data from the previous command to be overwritten.

2. After NCR5380_information_transfer() calls scsi_eh_prep_cmnd(),
   a new REQUEST SENSE command may arrive. This would be queued ahead
   of any command already undergoing autosense, which means the
   scsi_eh_save data might be restored to the wrong command.

3. After NCR5380_information_transfer() calls scsi_eh_prep_cmnd(),
   eh_abort_handler() may abort the command. But the scsi_eh_save data is
   not discarded, which means the scsi_eh_save data might be incorrectly
   restored to the next REQUEST SENSE command issued.

This patch adds a new autosense list so that commands that are re-queued
because of a CHECK CONDITION result can be kept apart from the REQUEST
SENSE commands that arrive via queuecommand.

This patch also adds a function dedicated to dequeueing and preparing the
next command for processing. By refactoring the main loop in this way,
scsi_eh_save takes place when an autosense command is dequeued rather
than when re-queued.

Signed-off-by: Finn Thain <fthain@telegraphics.com.au>

---
 drivers/scsi/NCR5380.c       |  194 +++++++++++++++++++---------------
 drivers/scsi/NCR5380.h       |    2 
 drivers/scsi/atari_NCR5380.c |  239 ++++++++++++++++++++++++-------------------
 3 files changed, 249 insertions(+), 186 deletions(-)

Index: linux/drivers/scsi/NCR5380.h
===================================================================
--- linux.orig/drivers/scsi/NCR5380.h	2015-11-18 19:34:20.000000000 +1100
+++ linux/drivers/scsi/NCR5380.h	2015-11-18 19:34:24.000000000 +1100
@@ -257,10 +257,12 @@ struct NCR5380_hostdata {
 	unsigned char last_message;		/* last message OUT */
 	struct scsi_cmnd *connected;		/* currently connected cmnd */
 	struct list_head unissued;		/* waiting to be issued */
+	struct list_head autosense;		/* priority issue queue */
 	struct list_head disconnected;		/* waiting for reconnect */
 	spinlock_t lock;			/* protects this struct */
 	int flags;
 	struct scsi_eh_save ses;
+	struct scsi_cmnd *sensing;
 	char info[256];
 	int read_overruns;                /* number of bytes to cut from a
 	                                   * transfer to handle chip overruns */
Index: linux/drivers/scsi/atari_NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/atari_NCR5380.c	2015-11-18 19:34:23.000000000 +1100
+++ linux/drivers/scsi/atari_NCR5380.c	2015-11-18 19:34:24.000000000 +1100
@@ -418,6 +418,9 @@ static inline void initialize_SCp(struct
 		cmd->SCp.ptr = NULL;
 		cmd->SCp.this_residual = 0;
 	}
+
+	cmd->SCp.Status = 0;
+	cmd->SCp.Message = 0;
 }
 
 /**
@@ -672,6 +675,8 @@ static int __init NCR5380_init(struct Sc
 #endif
 	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);
 
@@ -774,6 +779,16 @@ static void complete_cmd(struct Scsi_Hos
 
 	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
@@ -865,12 +880,77 @@ static inline void maybe_release_dma_irq
 	/* 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->retain_dma_intr)
 		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 (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) {
+		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
@@ -886,7 +966,7 @@ static void NCR5380_main(struct work_str
 	struct NCR5380_hostdata *hostdata =
 		container_of(work, struct NCR5380_hostdata, main_task);
 	struct Scsi_Host *instance = hostdata->host;
-	struct NCR5380_cmd *ncmd, *n;
+	struct scsi_cmnd *cmd;
 	int done;
 
 	/*
@@ -899,75 +979,46 @@ static void NCR5380_main(struct work_str
 	do {
 		done = 1;
 
-		if (!hostdata->connected) {
-			dprintk(NDEBUG_MAIN, "scsi%d: not connected\n", HOSTNO);
-			/*
-			 * Search through the issue_queue for a command destined
-			 * for a target that's not busy.
-			 */
-			list_for_each_entry_safe(ncmd, n, &hostdata->unissued,
-			                         list) {
-				struct scsi_cmnd *tmp = NCR5380_to_scmd(ncmd);
-				u8 lun = tmp->device->lun;
-
-				dsprintk(NDEBUG_QUEUES, instance, "main: tmp=%p target=%d busy=%d lun=%d\n",
-				         tmp, scmd_id(tmp), hostdata->busy[scmd_id(tmp)], lun);
-				/*  When we find one, remove it from the issue queue. */
-				if (
-#ifdef SUPPORT_TAGS
-				    !is_lun_busy( tmp, tmp->cmnd[0] != REQUEST_SENSE)
-#else
-				    !(hostdata->busy[tmp->device->id] & (1 << lun))
-#endif
-				    ) {
-					list_del(&ncmd->list);
-					dsprintk(NDEBUG_MAIN | NDEBUG_QUEUES,
-					         instance, "main: removed %p from issue queue\n",
-					         tmp);
+		while (!hostdata->connected &&
+		       (cmd = dequeue_next_cmd(instance))) {
 
-					hostdata->retain_dma_intr++;
+			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.
-					 */
+			/*
+			 * 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(tmp, tmp->cmnd[0] != REQUEST_SENSE);
+			cmd_get_tag(cmd, cmd->cmnd[0] != REQUEST_SENSE);
 #endif
-					if (!NCR5380_select(instance, tmp)) {
-						/* OK or bad target */
-						hostdata->retain_dma_intr--;
-						maybe_release_dma_irq(instance);
-					} else {
-						/* Need to retry */
-						list_add(&ncmd->list, &hostdata->unissued);
-						dsprintk(NDEBUG_MAIN | NDEBUG_QUEUES,
-						         instance, "main: select() failed, %p returned to issue queue\n",
-						         tmp);
+			hostdata->retain_dma_intr++;
+			if (!NCR5380_select(instance, cmd)) {
+				dsprintk(NDEBUG_MAIN, instance, "main: selected target %d for command %p\n",
+				         scmd_id(cmd), cmd);
+				hostdata->retain_dma_intr--;
+				maybe_release_dma_irq(instance);
+			} else {
+				hostdata->retain_dma_intr--;
+				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(tmp);
+				cmd_free_tag(cmd);
 #endif
-						hostdata->retain_dma_intr--;
-						done = 0;
-					}
-					if (hostdata->connected)
-						break;
-				} /* if target/lun/target queue is not busy */
-			} /* for issue_queue */
-		} /* if (!hostdata->connected) */
-
+			}
+		}
 		if (hostdata->connected
 #ifdef REAL_DMA
 		    && !hostdata->dma_len
@@ -2011,48 +2062,21 @@ static void NCR5380_information_transfer
 					}
 #endif
 
-					/*
-					 * I'm not sure what the correct thing to do here is :
-					 *
-					 * If the command that just executed is NOT a request
-					 * sense, the obvious thing to do is to set the result
-					 * code to the values of the stored parameters.
-					 *
-					 * If it was a REQUEST SENSE command, we need some way to
-					 * differentiate between the failure code of the original
-					 * and the failure code of the REQUEST sense - the obvious
-					 * case is success, where we fall through and leave the
-					 * result code unchanged.
-					 *
-					 * The non-obvious place is where the REQUEST SENSE failed
-					 */
+					cmd->result &= ~0xffff;
+					cmd->result |= cmd->SCp.Status;
+					cmd->result |= cmd->SCp.Message << 8;
 
-					if (cmd->cmnd[0] != REQUEST_SENSE)
-						cmd->result = cmd->SCp.Status | (cmd->SCp.Message << 8);
-					else if (status_byte(cmd->SCp.Status) != GOOD)
-						cmd->result = (cmd->result & 0x00ffff) | (DID_ERROR << 16);
-
-					if ((cmd->cmnd[0] == REQUEST_SENSE) &&
-						hostdata->ses.cmd_len) {
-						scsi_eh_restore_cmnd(cmd, &hostdata->ses);
-						hostdata->ses.cmd_len = 0 ;
-					}
-
-					if ((cmd->cmnd[0] != REQUEST_SENSE) &&
-					    (status_byte(cmd->SCp.Status) == CHECK_CONDITION)) {
-						scsi_eh_prep_cmnd(cmd, &hostdata->ses, NULL, 0, ~0);
-
-						list_add(&ncmd->list, &hostdata->unissued);
-						dsprintk(NDEBUG_AUTOSENSE | NDEBUG_QUEUES,
-						         instance, "REQUEST SENSE cmd %p added to head of issue queue\n",
-						         cmd);
-#ifdef SUPPORT_TAGS
-						cmd_free_tag(cmd);
-#else
-						hostdata->busy[cmd->device->id] &= ~(1 << cmd->device->lun);
-#endif
-					} else {
+					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);
 					}
 
 					/*
@@ -2542,6 +2566,15 @@ static int NCR5380_bus_reset(struct scsi
 		dsprintk(NDEBUG_ABORT, instance, "reset aborted a connected command\n");
 	hostdata->connected = NULL;
 
+	if (hostdata->sensing) {
+		complete_cmd(instance, hostdata->sensing);
+		hostdata->sensing = NULL;
+	}
+
+	if (!list_empty(&hostdata->autosense))
+		dsprintk(NDEBUG_ABORT, instance, "reset aborted autosense list\n");
+	INIT_LIST_HEAD(&hostdata->autosense);
+
 	if (!list_empty(&hostdata->unissued))
 		dsprintk(NDEBUG_ABORT, instance, "reset aborted unissued list\n");
 	INIT_LIST_HEAD(&hostdata->unissued);
Index: linux/drivers/scsi/NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/NCR5380.c	2015-11-18 19:34:23.000000000 +1100
+++ linux/drivers/scsi/NCR5380.c	2015-11-18 19:34:24.000000000 +1100
@@ -244,6 +244,9 @@ static inline void initialize_SCp(struct
 		cmd->SCp.ptr = NULL;
 		cmd->SCp.this_residual = 0;
 	}
+
+	cmd->SCp.Status = 0;
+	cmd->SCp.Message = 0;
 }
 
 /**
@@ -633,6 +636,8 @@ static int NCR5380_init(struct Scsi_Host
 #endif
 	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);
 
@@ -734,6 +739,16 @@ static void complete_cmd(struct Scsi_Hos
 
 	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;
+	}
+
 	hostdata->busy[scmd_id(cmd)] &= ~(1 << cmd->device->lun);
 
 	cmd->scsi_done(cmd);
@@ -794,6 +809,64 @@ static int NCR5380_queue_command(struct
 }
 
 /**
+ * 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 (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 (!(hostdata->busy[scmd_id(cmd)] & (1 << cmd->device->lun))) {
+				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) {
+		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 
@@ -810,63 +883,40 @@ static void NCR5380_main(struct work_str
 	struct NCR5380_hostdata *hostdata =
 		container_of(work, struct NCR5380_hostdata, main_task);
 	struct Scsi_Host *instance = hostdata->host;
-	struct NCR5380_cmd *ncmd, *n;
+	struct scsi_cmnd *cmd;
 	int done;
 	
 	spin_lock_irq(&hostdata->lock);
 	do {
 		done = 1;
 
-		if (!hostdata->connected) {
-			dprintk(NDEBUG_MAIN, "scsi%d : not connected\n", instance->host_no);
+		while (!hostdata->connected &&
+		       (cmd = dequeue_next_cmd(instance))) {
+
+			dsprintk(NDEBUG_MAIN, instance, "main: dequeued %p\n", cmd);
+
 			/*
-			 * Search through the issue_queue for a command destined
-			 * for a target that's not busy.
+			 * 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.
 			 */
-			list_for_each_entry_safe(ncmd, n, &hostdata->unissued,
-			                         list) {
-				struct scsi_cmnd *tmp = NCR5380_to_scmd(ncmd);
-
-				dsprintk(NDEBUG_QUEUES, instance, "main: tmp=%p target=%d busy=%d lun=%llu\n",
-				         tmp, scmd_id(tmp), hostdata->busy[scmd_id(tmp)],
-				         tmp->device->lun);
-				/*  When we find one, remove it from the issue queue. */
-				if (!(hostdata->busy[tmp->device->id] &
-				      (1 << (u8)(tmp->device->lun & 0xff)))) {
-					list_del(&ncmd->list);
-					dsprintk(NDEBUG_MAIN | NDEBUG_QUEUES,
-					         instance, "main: removed %p from issue queue\n",
-					         tmp);
-
-					/* 
-					 * 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.
-					 */
-
-					if (!NCR5380_select(instance, tmp)) {
-						/* OK or bad target */
-					} else {
-						/* Need to retry */
-						list_add(&ncmd->list, &hostdata->unissued);
-						dsprintk(NDEBUG_MAIN | NDEBUG_QUEUES,
-						         instance, "main: select() failed, %p returned to issue queue\n",
-						         tmp);
-						done = 0;
-					}
-					if (hostdata->connected)
-						break;
-				}	/* if target/lun is not busy */
-			}	/* for */
-		}	/* if (!hostdata->connected) */
 
+			if (!NCR5380_select(instance, cmd)) {
+				dsprintk(NDEBUG_MAIN, instance, "main: selected target %d for command %p\n",
+				         scmd_id(cmd), cmd);
+			} else {
+				dsprintk(NDEBUG_MAIN | NDEBUG_QUEUES, instance,
+				         "main: select failed, returning %p to queue\n", cmd);
+				requeue_cmd(instance, cmd);
+			}
+		}
 		if (hostdata->connected
 #ifdef REAL_DMA
 		    && !hostdata->dmalen
@@ -1860,43 +1910,21 @@ static void NCR5380_information_transfer
 
 					hostdata->connected = NULL;
 
-					/* 
-					 * I'm not sure what the correct thing to do here is : 
-					 * 
-					 * If the command that just executed is NOT a request 
-					 * sense, the obvious thing to do is to set the result
-					 * code to the values of the stored parameters.
-					 * 
-					 * If it was a REQUEST SENSE command, we need some way 
-					 * to differentiate between the failure code of the original
-					 * and the failure code of the REQUEST sense - the obvious
-					 * case is success, where we fall through and leave the result
-					 * code unchanged.
-					 * 
-					 * The non-obvious place is where the REQUEST SENSE failed 
-					 */
-
-					if (cmd->cmnd[0] != REQUEST_SENSE)
-						cmd->result = cmd->SCp.Status | (cmd->SCp.Message << 8);
-					else if (status_byte(cmd->SCp.Status) != GOOD)
-						cmd->result = (cmd->result & 0x00ffff) | (DID_ERROR << 16);
-
-					if ((cmd->cmnd[0] == REQUEST_SENSE) &&
-						hostdata->ses.cmd_len) {
-						scsi_eh_restore_cmnd(cmd, &hostdata->ses);
-						hostdata->ses.cmd_len = 0 ;
-					}
-
-					if ((cmd->cmnd[0] != REQUEST_SENSE) && (status_byte(cmd->SCp.Status) == CHECK_CONDITION)) {
-						scsi_eh_prep_cmnd(cmd, &hostdata->ses, NULL, 0, ~0);
+					cmd->result &= ~0xffff;
+					cmd->result |= cmd->SCp.Status;
+					cmd->result |= cmd->SCp.Message << 8;
 
-						list_add(&ncmd->list, &hostdata->unissued);
-						dsprintk(NDEBUG_AUTOSENSE | NDEBUG_QUEUES,
-						         instance, "REQUEST SENSE cmd %p added to head of issue queue\n",
-						         cmd);
-						hostdata->busy[cmd->device->id] &= ~(1 << (cmd->device->lun & 0xFF));
-					} else {
+					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);
 					}
 
 					/* 



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

* [PATCH 59/71] ncr5380: Fix autosense bugs
@ 2015-11-18  8:35   ` Finn Thain
  0 siblings, 0 replies; 268+ messages in thread
From: Finn Thain @ 2015-11-18  8:35 UTC (permalink / raw)
  To: James E.J. Bottomley, Michael Schmitz, linux-m68k, linux-scsi,
	linux-kernel

[-- Attachment #1: ncr5380-autosense-queue --]
[-- Type: text/plain, Size: 21553 bytes --]

NCR5380_information_transfer() may re-queue a command for autosense,
after calling scsi_eh_prep_cmnd(). This creates several possibilities:

1. Reselection may intervene before the re-queued command gets processed.
   If the reconnected command then undergoes autosense, this causes the
   scsi_eh_save data from the previous command to be overwritten.

2. After NCR5380_information_transfer() calls scsi_eh_prep_cmnd(),
   a new REQUEST SENSE command may arrive. This would be queued ahead
   of any command already undergoing autosense, which means the
   scsi_eh_save data might be restored to the wrong command.

3. After NCR5380_information_transfer() calls scsi_eh_prep_cmnd(),
   eh_abort_handler() may abort the command. But the scsi_eh_save data is
   not discarded, which means the scsi_eh_save data might be incorrectly
   restored to the next REQUEST SENSE command issued.

This patch adds a new autosense list so that commands that are re-queued
because of a CHECK CONDITION result can be kept apart from the REQUEST
SENSE commands that arrive via queuecommand.

This patch also adds a function dedicated to dequeueing and preparing the
next command for processing. By refactoring the main loop in this way,
scsi_eh_save takes place when an autosense command is dequeued rather
than when re-queued.

Signed-off-by: Finn Thain <fthain@telegraphics.com.au>

---
 drivers/scsi/NCR5380.c       |  194 +++++++++++++++++++---------------
 drivers/scsi/NCR5380.h       |    2 
 drivers/scsi/atari_NCR5380.c |  239 ++++++++++++++++++++++++-------------------
 3 files changed, 249 insertions(+), 186 deletions(-)

Index: linux/drivers/scsi/NCR5380.h
===================================================================
--- linux.orig/drivers/scsi/NCR5380.h	2015-11-18 19:34:20.000000000 +1100
+++ linux/drivers/scsi/NCR5380.h	2015-11-18 19:34:24.000000000 +1100
@@ -257,10 +257,12 @@ struct NCR5380_hostdata {
 	unsigned char last_message;		/* last message OUT */
 	struct scsi_cmnd *connected;		/* currently connected cmnd */
 	struct list_head unissued;		/* waiting to be issued */
+	struct list_head autosense;		/* priority issue queue */
 	struct list_head disconnected;		/* waiting for reconnect */
 	spinlock_t lock;			/* protects this struct */
 	int flags;
 	struct scsi_eh_save ses;
+	struct scsi_cmnd *sensing;
 	char info[256];
 	int read_overruns;                /* number of bytes to cut from a
 	                                   * transfer to handle chip overruns */
Index: linux/drivers/scsi/atari_NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/atari_NCR5380.c	2015-11-18 19:34:23.000000000 +1100
+++ linux/drivers/scsi/atari_NCR5380.c	2015-11-18 19:34:24.000000000 +1100
@@ -418,6 +418,9 @@ static inline void initialize_SCp(struct
 		cmd->SCp.ptr = NULL;
 		cmd->SCp.this_residual = 0;
 	}
+
+	cmd->SCp.Status = 0;
+	cmd->SCp.Message = 0;
 }
 
 /**
@@ -672,6 +675,8 @@ static int __init NCR5380_init(struct Sc
 #endif
 	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);
 
@@ -774,6 +779,16 @@ static void complete_cmd(struct Scsi_Hos
 
 	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
@@ -865,12 +880,77 @@ static inline void maybe_release_dma_irq
 	/* 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->retain_dma_intr)
 		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 (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) {
+		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
@@ -886,7 +966,7 @@ static void NCR5380_main(struct work_str
 	struct NCR5380_hostdata *hostdata =
 		container_of(work, struct NCR5380_hostdata, main_task);
 	struct Scsi_Host *instance = hostdata->host;
-	struct NCR5380_cmd *ncmd, *n;
+	struct scsi_cmnd *cmd;
 	int done;
 
 	/*
@@ -899,75 +979,46 @@ static void NCR5380_main(struct work_str
 	do {
 		done = 1;
 
-		if (!hostdata->connected) {
-			dprintk(NDEBUG_MAIN, "scsi%d: not connected\n", HOSTNO);
-			/*
-			 * Search through the issue_queue for a command destined
-			 * for a target that's not busy.
-			 */
-			list_for_each_entry_safe(ncmd, n, &hostdata->unissued,
-			                         list) {
-				struct scsi_cmnd *tmp = NCR5380_to_scmd(ncmd);
-				u8 lun = tmp->device->lun;
-
-				dsprintk(NDEBUG_QUEUES, instance, "main: tmp=%p target=%d busy=%d lun=%d\n",
-				         tmp, scmd_id(tmp), hostdata->busy[scmd_id(tmp)], lun);
-				/*  When we find one, remove it from the issue queue. */
-				if (
-#ifdef SUPPORT_TAGS
-				    !is_lun_busy( tmp, tmp->cmnd[0] != REQUEST_SENSE)
-#else
-				    !(hostdata->busy[tmp->device->id] & (1 << lun))
-#endif
-				    ) {
-					list_del(&ncmd->list);
-					dsprintk(NDEBUG_MAIN | NDEBUG_QUEUES,
-					         instance, "main: removed %p from issue queue\n",
-					         tmp);
+		while (!hostdata->connected &&
+		       (cmd = dequeue_next_cmd(instance))) {
 
-					hostdata->retain_dma_intr++;
+			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.
-					 */
+			/*
+			 * 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(tmp, tmp->cmnd[0] != REQUEST_SENSE);
+			cmd_get_tag(cmd, cmd->cmnd[0] != REQUEST_SENSE);
 #endif
-					if (!NCR5380_select(instance, tmp)) {
-						/* OK or bad target */
-						hostdata->retain_dma_intr--;
-						maybe_release_dma_irq(instance);
-					} else {
-						/* Need to retry */
-						list_add(&ncmd->list, &hostdata->unissued);
-						dsprintk(NDEBUG_MAIN | NDEBUG_QUEUES,
-						         instance, "main: select() failed, %p returned to issue queue\n",
-						         tmp);
+			hostdata->retain_dma_intr++;
+			if (!NCR5380_select(instance, cmd)) {
+				dsprintk(NDEBUG_MAIN, instance, "main: selected target %d for command %p\n",
+				         scmd_id(cmd), cmd);
+				hostdata->retain_dma_intr--;
+				maybe_release_dma_irq(instance);
+			} else {
+				hostdata->retain_dma_intr--;
+				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(tmp);
+				cmd_free_tag(cmd);
 #endif
-						hostdata->retain_dma_intr--;
-						done = 0;
-					}
-					if (hostdata->connected)
-						break;
-				} /* if target/lun/target queue is not busy */
-			} /* for issue_queue */
-		} /* if (!hostdata->connected) */
-
+			}
+		}
 		if (hostdata->connected
 #ifdef REAL_DMA
 		    && !hostdata->dma_len
@@ -2011,48 +2062,21 @@ static void NCR5380_information_transfer
 					}
 #endif
 
-					/*
-					 * I'm not sure what the correct thing to do here is :
-					 *
-					 * If the command that just executed is NOT a request
-					 * sense, the obvious thing to do is to set the result
-					 * code to the values of the stored parameters.
-					 *
-					 * If it was a REQUEST SENSE command, we need some way to
-					 * differentiate between the failure code of the original
-					 * and the failure code of the REQUEST sense - the obvious
-					 * case is success, where we fall through and leave the
-					 * result code unchanged.
-					 *
-					 * The non-obvious place is where the REQUEST SENSE failed
-					 */
+					cmd->result &= ~0xffff;
+					cmd->result |= cmd->SCp.Status;
+					cmd->result |= cmd->SCp.Message << 8;
 
-					if (cmd->cmnd[0] != REQUEST_SENSE)
-						cmd->result = cmd->SCp.Status | (cmd->SCp.Message << 8);
-					else if (status_byte(cmd->SCp.Status) != GOOD)
-						cmd->result = (cmd->result & 0x00ffff) | (DID_ERROR << 16);
-
-					if ((cmd->cmnd[0] == REQUEST_SENSE) &&
-						hostdata->ses.cmd_len) {
-						scsi_eh_restore_cmnd(cmd, &hostdata->ses);
-						hostdata->ses.cmd_len = 0 ;
-					}
-
-					if ((cmd->cmnd[0] != REQUEST_SENSE) &&
-					    (status_byte(cmd->SCp.Status) == CHECK_CONDITION)) {
-						scsi_eh_prep_cmnd(cmd, &hostdata->ses, NULL, 0, ~0);
-
-						list_add(&ncmd->list, &hostdata->unissued);
-						dsprintk(NDEBUG_AUTOSENSE | NDEBUG_QUEUES,
-						         instance, "REQUEST SENSE cmd %p added to head of issue queue\n",
-						         cmd);
-#ifdef SUPPORT_TAGS
-						cmd_free_tag(cmd);
-#else
-						hostdata->busy[cmd->device->id] &= ~(1 << cmd->device->lun);
-#endif
-					} else {
+					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);
 					}
 
 					/*
@@ -2542,6 +2566,15 @@ static int NCR5380_bus_reset(struct scsi
 		dsprintk(NDEBUG_ABORT, instance, "reset aborted a connected command\n");
 	hostdata->connected = NULL;
 
+	if (hostdata->sensing) {
+		complete_cmd(instance, hostdata->sensing);
+		hostdata->sensing = NULL;
+	}
+
+	if (!list_empty(&hostdata->autosense))
+		dsprintk(NDEBUG_ABORT, instance, "reset aborted autosense list\n");
+	INIT_LIST_HEAD(&hostdata->autosense);
+
 	if (!list_empty(&hostdata->unissued))
 		dsprintk(NDEBUG_ABORT, instance, "reset aborted unissued list\n");
 	INIT_LIST_HEAD(&hostdata->unissued);
Index: linux/drivers/scsi/NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/NCR5380.c	2015-11-18 19:34:23.000000000 +1100
+++ linux/drivers/scsi/NCR5380.c	2015-11-18 19:34:24.000000000 +1100
@@ -244,6 +244,9 @@ static inline void initialize_SCp(struct
 		cmd->SCp.ptr = NULL;
 		cmd->SCp.this_residual = 0;
 	}
+
+	cmd->SCp.Status = 0;
+	cmd->SCp.Message = 0;
 }
 
 /**
@@ -633,6 +636,8 @@ static int NCR5380_init(struct Scsi_Host
 #endif
 	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);
 
@@ -734,6 +739,16 @@ static void complete_cmd(struct Scsi_Hos
 
 	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;
+	}
+
 	hostdata->busy[scmd_id(cmd)] &= ~(1 << cmd->device->lun);
 
 	cmd->scsi_done(cmd);
@@ -794,6 +809,64 @@ static int NCR5380_queue_command(struct
 }
 
 /**
+ * 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 (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 (!(hostdata->busy[scmd_id(cmd)] & (1 << cmd->device->lun))) {
+				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) {
+		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 
@@ -810,63 +883,40 @@ static void NCR5380_main(struct work_str
 	struct NCR5380_hostdata *hostdata =
 		container_of(work, struct NCR5380_hostdata, main_task);
 	struct Scsi_Host *instance = hostdata->host;
-	struct NCR5380_cmd *ncmd, *n;
+	struct scsi_cmnd *cmd;
 	int done;
 	
 	spin_lock_irq(&hostdata->lock);
 	do {
 		done = 1;
 
-		if (!hostdata->connected) {
-			dprintk(NDEBUG_MAIN, "scsi%d : not connected\n", instance->host_no);
+		while (!hostdata->connected &&
+		       (cmd = dequeue_next_cmd(instance))) {
+
+			dsprintk(NDEBUG_MAIN, instance, "main: dequeued %p\n", cmd);
+
 			/*
-			 * Search through the issue_queue for a command destined
-			 * for a target that's not busy.
+			 * 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.
 			 */
-			list_for_each_entry_safe(ncmd, n, &hostdata->unissued,
-			                         list) {
-				struct scsi_cmnd *tmp = NCR5380_to_scmd(ncmd);
-
-				dsprintk(NDEBUG_QUEUES, instance, "main: tmp=%p target=%d busy=%d lun=%llu\n",
-				         tmp, scmd_id(tmp), hostdata->busy[scmd_id(tmp)],
-				         tmp->device->lun);
-				/*  When we find one, remove it from the issue queue. */
-				if (!(hostdata->busy[tmp->device->id] &
-				      (1 << (u8)(tmp->device->lun & 0xff)))) {
-					list_del(&ncmd->list);
-					dsprintk(NDEBUG_MAIN | NDEBUG_QUEUES,
-					         instance, "main: removed %p from issue queue\n",
-					         tmp);
-
-					/* 
-					 * 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.
-					 */
-
-					if (!NCR5380_select(instance, tmp)) {
-						/* OK or bad target */
-					} else {
-						/* Need to retry */
-						list_add(&ncmd->list, &hostdata->unissued);
-						dsprintk(NDEBUG_MAIN | NDEBUG_QUEUES,
-						         instance, "main: select() failed, %p returned to issue queue\n",
-						         tmp);
-						done = 0;
-					}
-					if (hostdata->connected)
-						break;
-				}	/* if target/lun is not busy */
-			}	/* for */
-		}	/* if (!hostdata->connected) */
 
+			if (!NCR5380_select(instance, cmd)) {
+				dsprintk(NDEBUG_MAIN, instance, "main: selected target %d for command %p\n",
+				         scmd_id(cmd), cmd);
+			} else {
+				dsprintk(NDEBUG_MAIN | NDEBUG_QUEUES, instance,
+				         "main: select failed, returning %p to queue\n", cmd);
+				requeue_cmd(instance, cmd);
+			}
+		}
 		if (hostdata->connected
 #ifdef REAL_DMA
 		    && !hostdata->dmalen
@@ -1860,43 +1910,21 @@ static void NCR5380_information_transfer
 
 					hostdata->connected = NULL;
 
-					/* 
-					 * I'm not sure what the correct thing to do here is : 
-					 * 
-					 * If the command that just executed is NOT a request 
-					 * sense, the obvious thing to do is to set the result
-					 * code to the values of the stored parameters.
-					 * 
-					 * If it was a REQUEST SENSE command, we need some way 
-					 * to differentiate between the failure code of the original
-					 * and the failure code of the REQUEST sense - the obvious
-					 * case is success, where we fall through and leave the result
-					 * code unchanged.
-					 * 
-					 * The non-obvious place is where the REQUEST SENSE failed 
-					 */
-
-					if (cmd->cmnd[0] != REQUEST_SENSE)
-						cmd->result = cmd->SCp.Status | (cmd->SCp.Message << 8);
-					else if (status_byte(cmd->SCp.Status) != GOOD)
-						cmd->result = (cmd->result & 0x00ffff) | (DID_ERROR << 16);
-
-					if ((cmd->cmnd[0] == REQUEST_SENSE) &&
-						hostdata->ses.cmd_len) {
-						scsi_eh_restore_cmnd(cmd, &hostdata->ses);
-						hostdata->ses.cmd_len = 0 ;
-					}
-
-					if ((cmd->cmnd[0] != REQUEST_SENSE) && (status_byte(cmd->SCp.Status) == CHECK_CONDITION)) {
-						scsi_eh_prep_cmnd(cmd, &hostdata->ses, NULL, 0, ~0);
+					cmd->result &= ~0xffff;
+					cmd->result |= cmd->SCp.Status;
+					cmd->result |= cmd->SCp.Message << 8;
 
-						list_add(&ncmd->list, &hostdata->unissued);
-						dsprintk(NDEBUG_AUTOSENSE | NDEBUG_QUEUES,
-						         instance, "REQUEST SENSE cmd %p added to head of issue queue\n",
-						         cmd);
-						hostdata->busy[cmd->device->id] &= ~(1 << (cmd->device->lun & 0xFF));
-					} else {
+					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);
 					}
 
 					/* 

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

* [PATCH 60/71] ncr5380: Implement new eh_abort_handler
  2015-11-18  8:34 ` Finn Thain
@ 2015-11-18  8:35   ` Finn Thain
  -1 siblings, 0 replies; 268+ messages in thread
From: Finn Thain @ 2015-11-18  8:35 UTC (permalink / raw)
  To: James E.J. Bottomley, Michael Schmitz, linux-m68k, linux-scsi,
	linux-kernel

[-- Attachment #1: ncr5380-new-eh_abort_handler --]
[-- Type: text/plain, Size: 12475 bytes --]

Introduce a new eh_abort_handler implementation. This one attempts to
follow all of the rules relating to EH handlers. There is still a known
bug: during selection, a command becomes invisible to the EH handlers
because it only appears in a pointer on the stack of a different thread.
This bug is addressed in a subsequent patch.

Signed-off-by: Finn Thain <fthain@telegraphics.com.au>

---
 drivers/scsi/NCR5380.c       |  155 ++++++++++++++++++++++++++++++++++++++----
 drivers/scsi/atari_NCR5380.c |  157 ++++++++++++++++++++++++++++++++++++++-----
 2 files changed, 282 insertions(+), 30 deletions(-)

Index: linux/drivers/scsi/atari_NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/atari_NCR5380.c	2015-11-18 19:34:24.000000000 +1100
+++ linux/drivers/scsi/atari_NCR5380.c	2015-11-18 19:34:27.000000000 +1100
@@ -2489,41 +2489,168 @@ static void NCR5380_reselect(struct Scsi
 }
 
 
-/*
- * Function : int NCR5380_abort (struct scsi_cmnd *cmd)
+/**
+ * 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
  *
- * Purpose : abort a command
+ * 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.
  *
- * Inputs : cmd - the scsi_cmnd to abort, code - code to set the
- *	host byte of the result field to, if zero DID_ABORTED is
- *	used.
+ * The normal path taken by a command is as follows. For EH we trace this
+ * same path to locate and abort the command.
  *
- * Returns : SUCCESS - success, FAILED on failure.
+ * unissued -> selecting -> [unissued -> selecting ->]... connected ->
+ * [disconnected -> connected ->]...
+ * [autosense -> connected ->] done
  *
- * XXX - there is no way to abort the command that is currently
- *	 connected, you have to wait for it to complete.  If this is
- *	 a problem, we could implement longjmp() / setjmp(), setjmp()
- *	 called where the loop started in NCR5380_main().
+ * If cmd is unissued then just remove it.
+ * If cmd is disconnected, try to select the target.
+ * If cmd is connected, try to send an abort message.
+ * If cmd is waiting for autosense, give it a chance to complete but check
+ * that it isn't left connected.
+ * 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.
  */
 
-static
-int NCR5380_abort(struct scsi_cmnd *cmd)
+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, "aborting command\n");
+	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 */
+	}
+
+	if (list_del_cmd(&hostdata->disconnected, cmd)) {
+		dsprintk(NDEBUG_ABORT, instance,
+		         "abort: removed %p from disconnected list\n", cmd);
+		cmd->result = DID_ERROR << 16;
+		if (!hostdata->connected)
+			NCR5380_select(instance, cmd);
+		if (hostdata->connected != cmd) {
+			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;
+		if (do_abort(instance)) {
+			set_host_byte(cmd, DID_ERROR);
+			complete_cmd(instance, cmd);
+			result = FAILED;
+			goto out;
+		}
+		set_host_byte(cmd, DID_ABORT);
+#ifdef REAL_DMA
+		hostdata->dma_len = 0;
+#endif
+		if (cmd->cmnd[0] == REQUEST_SENSE)
+			complete_cmd(instance, cmd);
+		else {
+			struct NCR5380_cmd *ncmd = scsi_cmd_priv(cmd);
+
+			/* Perform autosense for this command */
+			list_add(&ncmd->list, &hostdata->autosense);
+		}
+	}
+
+	if (list_find_cmd(&hostdata->autosense, cmd)) {
+		dsprintk(NDEBUG_ABORT, instance,
+		         "abort: found %p on sense queue\n", cmd);
+		spin_unlock_irqrestore(&hostdata->lock, flags);
+		queue_work(hostdata->work_q, &hostdata->main_task);
+		msleep(1000);
+		spin_lock_irqsave(&hostdata->lock, flags);
+		if (list_del_cmd(&hostdata->autosense, cmd)) {
+			dsprintk(NDEBUG_ABORT, instance,
+			         "abort: removed %p from sense queue\n", cmd);
+			set_host_byte(cmd, DID_ABORT);
+			complete_cmd(instance, cmd);
+			goto out;
+		}
+	}
+
+	if (hostdata->connected == cmd) {
+		dsprintk(NDEBUG_ABORT, instance, "abort: cmd %p is connected\n", cmd);
+		hostdata->connected = NULL;
+		if (do_abort(instance)) {
+			set_host_byte(cmd, DID_ERROR);
+			complete_cmd(instance, cmd);
+			result = FAILED;
+			goto out;
+		}
+		set_host_byte(cmd, DID_ABORT);
+#ifdef REAL_DMA
+		hostdata->dma_len = 0;
+#endif
+		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 FAILED;
+	return result;
 }
 
 
Index: linux/drivers/scsi/NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/NCR5380.c	2015-11-18 19:34:24.000000000 +1100
+++ linux/drivers/scsi/NCR5380.c	2015-11-18 19:34:27.000000000 +1100
@@ -2276,23 +2276,65 @@ static void NCR5380_dma_complete(NCR5380
 }
 #endif				/* def REAL_DMA */
 
-/*
- * Function : int NCR5380_abort (struct scsi_cmnd *cmd)
- *
- * Purpose : abort a command
+/**
+ * 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
  *
- * Inputs : cmd - the scsi_cmnd to abort, code - code to set the
- *      host byte of the result field to, if zero DID_ABORTED is
- *      used.
+ * 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.
  *
- * Returns : SUCCESS - success, FAILED on failure.
+ * The normal path taken by a command is as follows. For EH we trace this
+ * same path to locate and abort the command.
  *
- *	XXX - there is no way to abort the command that is currently
- *	connected, you have to wait for it to complete.  If this is
- *	a problem, we could implement longjmp() / setjmp(), setjmp()
- *	called where the loop started in NCR5380_main().
+ * unissued -> selecting -> [unissued -> selecting ->]... connected ->
+ * [disconnected -> connected ->]...
+ * [autosense -> connected ->] done
  *
- * Locks: host lock taken by caller
+ * If cmd is unissued then just remove it.
+ * If cmd is disconnected, try to select the target.
+ * If cmd is connected, try to send an abort message.
+ * If cmd is waiting for autosense, give it a chance to complete but check
+ * that it isn't left connected.
+ * 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.
  */
 
 static int NCR5380_abort(struct scsi_cmnd *cmd)
@@ -2300,18 +2342,101 @@ static int NCR5380_abort(struct scsi_cmn
 	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, "aborting command\n");
+	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 */
+	}
+
+	if (list_del_cmd(&hostdata->disconnected, cmd)) {
+		dsprintk(NDEBUG_ABORT, instance,
+		         "abort: removed %p from disconnected list\n", cmd);
+		cmd->result = DID_ERROR << 16;
+		if (!hostdata->connected)
+			NCR5380_select(instance, cmd);
+		if (hostdata->connected != cmd) {
+			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;
+		if (do_abort(instance)) {
+			set_host_byte(cmd, DID_ERROR);
+			complete_cmd(instance, cmd);
+			result = FAILED;
+			goto out;
+		}
+		set_host_byte(cmd, DID_ABORT);
+#ifdef REAL_DMA
+		hostdata->dma_len = 0;
+#endif
+		if (cmd->cmnd[0] == REQUEST_SENSE)
+			complete_cmd(instance, cmd);
+		else {
+			struct NCR5380_cmd *ncmd = scsi_cmd_priv(cmd);
+
+			/* Perform autosense for this command */
+			list_add(&ncmd->list, &hostdata->autosense);
+		}
+	}
+
+	if (list_find_cmd(&hostdata->autosense, cmd)) {
+		dsprintk(NDEBUG_ABORT, instance,
+		         "abort: found %p on sense queue\n", cmd);
+		spin_unlock_irqrestore(&hostdata->lock, flags);
+		queue_work(hostdata->work_q, &hostdata->main_task);
+		msleep(1000);
+		spin_lock_irqsave(&hostdata->lock, flags);
+		if (list_del_cmd(&hostdata->autosense, cmd)) {
+			dsprintk(NDEBUG_ABORT, instance,
+			         "abort: removed %p from sense queue\n", cmd);
+			set_host_byte(cmd, DID_ABORT);
+			complete_cmd(instance, cmd);
+			goto out;
+		}
+	}
+
+	if (hostdata->connected == cmd) {
+		dsprintk(NDEBUG_ABORT, instance, "abort: cmd %p is connected\n", cmd);
+		hostdata->connected = NULL;
+		if (do_abort(instance)) {
+			set_host_byte(cmd, DID_ERROR);
+			complete_cmd(instance, cmd);
+			result = FAILED;
+			goto out;
+		}
+		set_host_byte(cmd, DID_ABORT);
+#ifdef REAL_DMA
+		hostdata->dma_len = 0;
+#endif
+		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);
 	spin_unlock_irqrestore(&hostdata->lock, flags);
 
-	return FAILED;
+	return result;
 }
 
 



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

* [PATCH 60/71] ncr5380: Implement new eh_abort_handler
@ 2015-11-18  8:35   ` Finn Thain
  0 siblings, 0 replies; 268+ messages in thread
From: Finn Thain @ 2015-11-18  8:35 UTC (permalink / raw)
  To: James E.J. Bottomley, Michael Schmitz, linux-m68k, linux-scsi,
	linux-kernel

[-- Attachment #1: ncr5380-new-eh_abort_handler --]
[-- Type: text/plain, Size: 12475 bytes --]

Introduce a new eh_abort_handler implementation. This one attempts to
follow all of the rules relating to EH handlers. There is still a known
bug: during selection, a command becomes invisible to the EH handlers
because it only appears in a pointer on the stack of a different thread.
This bug is addressed in a subsequent patch.

Signed-off-by: Finn Thain <fthain@telegraphics.com.au>

---
 drivers/scsi/NCR5380.c       |  155 ++++++++++++++++++++++++++++++++++++++----
 drivers/scsi/atari_NCR5380.c |  157 ++++++++++++++++++++++++++++++++++++++-----
 2 files changed, 282 insertions(+), 30 deletions(-)

Index: linux/drivers/scsi/atari_NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/atari_NCR5380.c	2015-11-18 19:34:24.000000000 +1100
+++ linux/drivers/scsi/atari_NCR5380.c	2015-11-18 19:34:27.000000000 +1100
@@ -2489,41 +2489,168 @@ static void NCR5380_reselect(struct Scsi
 }
 
 
-/*
- * Function : int NCR5380_abort (struct scsi_cmnd *cmd)
+/**
+ * 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
  *
- * Purpose : abort a command
+ * 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.
  *
- * Inputs : cmd - the scsi_cmnd to abort, code - code to set the
- *	host byte of the result field to, if zero DID_ABORTED is
- *	used.
+ * The normal path taken by a command is as follows. For EH we trace this
+ * same path to locate and abort the command.
  *
- * Returns : SUCCESS - success, FAILED on failure.
+ * unissued -> selecting -> [unissued -> selecting ->]... connected ->
+ * [disconnected -> connected ->]...
+ * [autosense -> connected ->] done
  *
- * XXX - there is no way to abort the command that is currently
- *	 connected, you have to wait for it to complete.  If this is
- *	 a problem, we could implement longjmp() / setjmp(), setjmp()
- *	 called where the loop started in NCR5380_main().
+ * If cmd is unissued then just remove it.
+ * If cmd is disconnected, try to select the target.
+ * If cmd is connected, try to send an abort message.
+ * If cmd is waiting for autosense, give it a chance to complete but check
+ * that it isn't left connected.
+ * 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.
  */
 
-static
-int NCR5380_abort(struct scsi_cmnd *cmd)
+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, "aborting command\n");
+	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 */
+	}
+
+	if (list_del_cmd(&hostdata->disconnected, cmd)) {
+		dsprintk(NDEBUG_ABORT, instance,
+		         "abort: removed %p from disconnected list\n", cmd);
+		cmd->result = DID_ERROR << 16;
+		if (!hostdata->connected)
+			NCR5380_select(instance, cmd);
+		if (hostdata->connected != cmd) {
+			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;
+		if (do_abort(instance)) {
+			set_host_byte(cmd, DID_ERROR);
+			complete_cmd(instance, cmd);
+			result = FAILED;
+			goto out;
+		}
+		set_host_byte(cmd, DID_ABORT);
+#ifdef REAL_DMA
+		hostdata->dma_len = 0;
+#endif
+		if (cmd->cmnd[0] == REQUEST_SENSE)
+			complete_cmd(instance, cmd);
+		else {
+			struct NCR5380_cmd *ncmd = scsi_cmd_priv(cmd);
+
+			/* Perform autosense for this command */
+			list_add(&ncmd->list, &hostdata->autosense);
+		}
+	}
+
+	if (list_find_cmd(&hostdata->autosense, cmd)) {
+		dsprintk(NDEBUG_ABORT, instance,
+		         "abort: found %p on sense queue\n", cmd);
+		spin_unlock_irqrestore(&hostdata->lock, flags);
+		queue_work(hostdata->work_q, &hostdata->main_task);
+		msleep(1000);
+		spin_lock_irqsave(&hostdata->lock, flags);
+		if (list_del_cmd(&hostdata->autosense, cmd)) {
+			dsprintk(NDEBUG_ABORT, instance,
+			         "abort: removed %p from sense queue\n", cmd);
+			set_host_byte(cmd, DID_ABORT);
+			complete_cmd(instance, cmd);
+			goto out;
+		}
+	}
+
+	if (hostdata->connected == cmd) {
+		dsprintk(NDEBUG_ABORT, instance, "abort: cmd %p is connected\n", cmd);
+		hostdata->connected = NULL;
+		if (do_abort(instance)) {
+			set_host_byte(cmd, DID_ERROR);
+			complete_cmd(instance, cmd);
+			result = FAILED;
+			goto out;
+		}
+		set_host_byte(cmd, DID_ABORT);
+#ifdef REAL_DMA
+		hostdata->dma_len = 0;
+#endif
+		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 FAILED;
+	return result;
 }
 
 
Index: linux/drivers/scsi/NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/NCR5380.c	2015-11-18 19:34:24.000000000 +1100
+++ linux/drivers/scsi/NCR5380.c	2015-11-18 19:34:27.000000000 +1100
@@ -2276,23 +2276,65 @@ static void NCR5380_dma_complete(NCR5380
 }
 #endif				/* def REAL_DMA */
 
-/*
- * Function : int NCR5380_abort (struct scsi_cmnd *cmd)
- *
- * Purpose : abort a command
+/**
+ * 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
  *
- * Inputs : cmd - the scsi_cmnd to abort, code - code to set the
- *      host byte of the result field to, if zero DID_ABORTED is
- *      used.
+ * 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.
  *
- * Returns : SUCCESS - success, FAILED on failure.
+ * The normal path taken by a command is as follows. For EH we trace this
+ * same path to locate and abort the command.
  *
- *	XXX - there is no way to abort the command that is currently
- *	connected, you have to wait for it to complete.  If this is
- *	a problem, we could implement longjmp() / setjmp(), setjmp()
- *	called where the loop started in NCR5380_main().
+ * unissued -> selecting -> [unissued -> selecting ->]... connected ->
+ * [disconnected -> connected ->]...
+ * [autosense -> connected ->] done
  *
- * Locks: host lock taken by caller
+ * If cmd is unissued then just remove it.
+ * If cmd is disconnected, try to select the target.
+ * If cmd is connected, try to send an abort message.
+ * If cmd is waiting for autosense, give it a chance to complete but check
+ * that it isn't left connected.
+ * 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.
  */
 
 static int NCR5380_abort(struct scsi_cmnd *cmd)
@@ -2300,18 +2342,101 @@ static int NCR5380_abort(struct scsi_cmn
 	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, "aborting command\n");
+	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 */
+	}
+
+	if (list_del_cmd(&hostdata->disconnected, cmd)) {
+		dsprintk(NDEBUG_ABORT, instance,
+		         "abort: removed %p from disconnected list\n", cmd);
+		cmd->result = DID_ERROR << 16;
+		if (!hostdata->connected)
+			NCR5380_select(instance, cmd);
+		if (hostdata->connected != cmd) {
+			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;
+		if (do_abort(instance)) {
+			set_host_byte(cmd, DID_ERROR);
+			complete_cmd(instance, cmd);
+			result = FAILED;
+			goto out;
+		}
+		set_host_byte(cmd, DID_ABORT);
+#ifdef REAL_DMA
+		hostdata->dma_len = 0;
+#endif
+		if (cmd->cmnd[0] == REQUEST_SENSE)
+			complete_cmd(instance, cmd);
+		else {
+			struct NCR5380_cmd *ncmd = scsi_cmd_priv(cmd);
+
+			/* Perform autosense for this command */
+			list_add(&ncmd->list, &hostdata->autosense);
+		}
+	}
+
+	if (list_find_cmd(&hostdata->autosense, cmd)) {
+		dsprintk(NDEBUG_ABORT, instance,
+		         "abort: found %p on sense queue\n", cmd);
+		spin_unlock_irqrestore(&hostdata->lock, flags);
+		queue_work(hostdata->work_q, &hostdata->main_task);
+		msleep(1000);
+		spin_lock_irqsave(&hostdata->lock, flags);
+		if (list_del_cmd(&hostdata->autosense, cmd)) {
+			dsprintk(NDEBUG_ABORT, instance,
+			         "abort: removed %p from sense queue\n", cmd);
+			set_host_byte(cmd, DID_ABORT);
+			complete_cmd(instance, cmd);
+			goto out;
+		}
+	}
+
+	if (hostdata->connected == cmd) {
+		dsprintk(NDEBUG_ABORT, instance, "abort: cmd %p is connected\n", cmd);
+		hostdata->connected = NULL;
+		if (do_abort(instance)) {
+			set_host_byte(cmd, DID_ERROR);
+			complete_cmd(instance, cmd);
+			result = FAILED;
+			goto out;
+		}
+		set_host_byte(cmd, DID_ABORT);
+#ifdef REAL_DMA
+		hostdata->dma_len = 0;
+#endif
+		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);
 	spin_unlock_irqrestore(&hostdata->lock, flags);
 
-	return FAILED;
+	return result;
 }
 
 



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

* [PATCH 61/71] ncr5380: Fix EH during arbitration and selection
  2015-11-18  8:34 ` Finn Thain
@ 2015-11-18  8:35   ` Finn Thain
  -1 siblings, 0 replies; 268+ messages in thread
From: Finn Thain @ 2015-11-18  8:35 UTC (permalink / raw)
  To: James E.J. Bottomley, Michael Schmitz, linux-m68k, linux-scsi,
	linux-kernel

[-- Attachment #1: ncr5380-fix-abort-during-select --]
[-- Type: text/plain, Size: 15500 bytes --]

During arbitration and selection, the relevant command is invisible to
exception handlers and can be found only in a pointer on the stack of a
different thread.

When eh_abort_handler can't find a given command, it can't decide whether
that command was completed already or is still in arbitration or selection
phase. But it must return either SUCCESS (e.g. command completed earlier)
or FAILED (could not abort the nexus, try bus reset).

The solution is to make sure all commands belonging to the LLD are always
visible to exception handlers. Add another scsi_cmnd pointer to the
hostdata struct to track the command in arbitration or selection phase.

Replace 'retain_dma_irq' with the new 'selecting' pointer, to bring
atari_NCR5380.c into line with NCR5380.c.

Signed-off-by: Finn Thain <fthain@telegraphics.com.au>

---
 drivers/scsi/NCR5380.c       |   78 +++++++++++++++++++++++++++++----------
 drivers/scsi/NCR5380.h       |    4 +-
 drivers/scsi/atari_NCR5380.c |   84 +++++++++++++++++++++++++++++++------------
 3 files changed, 121 insertions(+), 45 deletions(-)

Index: linux/drivers/scsi/NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/NCR5380.c	2015-11-18 19:34:27.000000000 +1100
+++ linux/drivers/scsi/NCR5380.c	2015-11-18 19:34:29.000000000 +1100
@@ -908,9 +908,9 @@ static void NCR5380_main(struct work_str
 			 * entire unit.
 			 */
 
-			if (!NCR5380_select(instance, cmd)) {
-				dsprintk(NDEBUG_MAIN, instance, "main: selected target %d for command %p\n",
-				         scmd_id(cmd), cmd);
+			cmd = NCR5380_select(instance, cmd);
+			if (!cmd) {
+				dsprintk(NDEBUG_MAIN, instance, "main: select complete\n");
 			} else {
 				dsprintk(NDEBUG_MAIN | NDEBUG_QUEUES, instance,
 				         "main: select failed, returning %p to queue\n", cmd);
@@ -1057,9 +1057,9 @@ static irqreturn_t NCR5380_intr(int irq,
  * Inputs : instance - instantiation of the 5380 driver on which this 
  *      target lives, cmd - SCSI command to execute.
  * 
- * Returns : -1 if selection failed but should be retried.
- *      0 if selection failed and should not be retried.
- *      0 if selection succeeded completely (hostdata->connected == cmd).
+ * 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 
@@ -1077,7 +1077,8 @@ static irqreturn_t NCR5380_intr(int irq,
  *	Locks: caller holds hostdata lock in IRQ mode
  */
  
-static int NCR5380_select(struct Scsi_Host *instance, struct scsi_cmnd *cmd)
+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;
@@ -1088,6 +1089,15 @@ static int NCR5380_select(struct Scsi_Ho
 	NCR5380_dprint(NDEBUG_ARBITRATION, instance);
 	dprintk(NDEBUG_ARBITRATION, "scsi%d : starting arbitration, id = %d\n", instance->host_no, 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.
@@ -1113,13 +1123,13 @@ static int NCR5380_select(struct Scsi_Ho
 	spin_lock_irq(&hostdata->lock);
 	if (!(NCR5380_read(MODE_REG) & MR_ARBITRATE)) {
 		/* Reselection interrupt */
-		return -1;
+		goto out;
 	}
 	if (err < 0) {
 		NCR5380_write(MODE_REG, MR_BASE);
 		shost_printk(KERN_ERR, instance,
 		             "select: arbitration timeout\n");
-		return -1;
+		goto out;
 	}
 	spin_unlock_irq(&hostdata->lock);
 
@@ -1131,7 +1141,7 @@ static int NCR5380_select(struct Scsi_Ho
 		NCR5380_write(MODE_REG, MR_BASE);
 		dprintk(NDEBUG_ARBITRATION, "scsi%d : lost arbitration, deasserting MR_ARBITRATE\n", instance->host_no);
 		spin_lock_irq(&hostdata->lock);
-		return -1;
+		goto out;
 	}
 
 	/* After/during arbitration, BSY should be asserted.
@@ -1150,7 +1160,7 @@ static int NCR5380_select(struct Scsi_Ho
 		NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
 		dsprintk(NDEBUG_ARBITRATION, instance, "arbitration lost, negating SEL\n");
 		spin_lock_irq(&hostdata->lock);
-		return -1;
+		goto out;
 	}
 	/* 
 	 * Again, bus clear + bus settle time is 1.2us, however, this is 
@@ -1166,7 +1176,13 @@ static int NCR5380_select(struct Scsi_Ho
 
 	/* NCR5380_reselect() clears MODE_REG after a reselection interrupt */
 	if (!(NCR5380_read(MODE_REG) & MR_ARBITRATE))
-		return -1;
+		goto out;
+
+	if (!hostdata->selecting) {
+		NCR5380_write(MODE_REG, MR_BASE);
+		NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
+		goto out;
+	}
 
 	dprintk(NDEBUG_ARBITRATION, "scsi%d : won arbitration\n", instance->host_no);
 
@@ -1239,18 +1255,21 @@ static int NCR5380_select(struct Scsi_Ho
 		if (!hostdata->connected)
 			NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
 		printk("scsi%d : reselection after won arbitration?\n", instance->host_no);
-		return -1;
+		goto out;
 	}
 
 	if (err < 0) {
 		spin_lock_irq(&hostdata->lock);
 		NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
-		cmd->result = DID_BAD_TARGET << 16;
-		complete_cmd(instance, cmd);
 		NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
-		dprintk(NDEBUG_SELECTION, "scsi%d : target did not respond within 250ms\n",
-		        instance->host_no);
-		return 0;
+		/* 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;
 	}
 
 	/* 
@@ -1286,7 +1305,11 @@ static int NCR5380_select(struct Scsi_Ho
 		shost_printk(KERN_ERR, instance, "select: REQ timeout\n");
 		NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
 		NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
-		return -1;
+		goto out;
+	}
+	if (!hostdata->selecting) {
+		do_abort(instance);
+		goto out;
 	}
 
 	dprintk(NDEBUG_SELECTION, "scsi%d : target %d selected, going into MESSAGE OUT phase.\n", instance->host_no, cmd->device->id);
@@ -1307,7 +1330,13 @@ static int NCR5380_select(struct Scsi_Ho
 
 	initialize_SCp(cmd);
 
-	return 0;
+	cmd = NULL;
+
+out:
+	if (!hostdata->selecting)
+		return NULL;
+	hostdata->selecting = NULL;
+	return cmd;
 }
 
 /* 
@@ -2359,6 +2388,15 @@ static int NCR5380_abort(struct scsi_cmn
 		cmd->scsi_done(cmd); /* No tag or busy flag to worry about */
 	}
 
+	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);
Index: linux/drivers/scsi/NCR5380.h
===================================================================
--- linux.orig/drivers/scsi/NCR5380.h	2015-11-18 19:34:24.000000000 +1100
+++ linux/drivers/scsi/NCR5380.h	2015-11-18 19:34:29.000000000 +1100
@@ -256,6 +256,7 @@ struct NCR5380_hostdata {
 #endif
 	unsigned char last_message;		/* last message OUT */
 	struct scsi_cmnd *connected;		/* currently connected cmnd */
+	struct scsi_cmnd *selecting;		/* cmnd to be connected */
 	struct list_head unissued;		/* waiting to be issued */
 	struct list_head autosense;		/* priority issue queue */
 	struct list_head disconnected;		/* waiting for reconnect */
@@ -266,7 +267,6 @@ struct NCR5380_hostdata {
 	char info[256];
 	int read_overruns;                /* number of bytes to cut from a
 	                                   * transfer to handle chip overruns */
-	int retain_dma_intr;
 	struct work_struct main_task;
 #ifdef SUPPORT_TAGS
 	struct tag_alloc TagAlloc[8][8];	/* 8 targets and 8 LUNs */
@@ -329,7 +329,7 @@ static irqreturn_t NCR5380_intr(int irq,
 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);
-static int NCR5380_select(struct Scsi_Host *instance, struct scsi_cmnd *cmd);
+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
Index: linux/drivers/scsi/atari_NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/atari_NCR5380.c	2015-11-18 19:34:27.000000000 +1100
+++ linux/drivers/scsi/atari_NCR5380.c	2015-11-18 19:34:29.000000000 +1100
@@ -882,7 +882,7 @@ static inline void maybe_release_dma_irq
 	    list_empty(&hostdata->unissued) &&
 	    list_empty(&hostdata->autosense) &&
 	    !hostdata->connected &&
-	    !hostdata->retain_dma_intr)
+	    !hostdata->selecting)
 		NCR5380_release_dma_irq(instance);
 }
 
@@ -1003,14 +1003,11 @@ static void NCR5380_main(struct work_str
 #ifdef SUPPORT_TAGS
 			cmd_get_tag(cmd, cmd->cmnd[0] != REQUEST_SENSE);
 #endif
-			hostdata->retain_dma_intr++;
-			if (!NCR5380_select(instance, cmd)) {
-				dsprintk(NDEBUG_MAIN, instance, "main: selected target %d for command %p\n",
-				         scmd_id(cmd), cmd);
-				hostdata->retain_dma_intr--;
+			cmd = NCR5380_select(instance, cmd);
+			if (!cmd) {
+				dsprintk(NDEBUG_MAIN, instance, "main: select complete\n");
 				maybe_release_dma_irq(instance);
 			} else {
-				hostdata->retain_dma_intr--;
 				dsprintk(NDEBUG_MAIN | NDEBUG_QUEUES, instance,
 				         "main: select failed, returning %p to queue\n", cmd);
 				requeue_cmd(instance, cmd);
@@ -1238,9 +1235,9 @@ static irqreturn_t NCR5380_intr(int irq,
  * Inputs : instance - instantiation of the 5380 driver on which this
  *	target lives, cmd - SCSI command to execute.
  *
- * Returns : -1 if selection failed but should be retried.
- *      0 if selection failed and should not be retried.
- *      0 if selection succeeded completely (hostdata->connected == cmd).
+ * 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
@@ -1256,7 +1253,8 @@ static irqreturn_t NCR5380_intr(int irq,
  *		cmd->result host byte set to DID_BAD_TARGET.
  */
 
-static int NCR5380_select(struct Scsi_Host *instance, struct scsi_cmnd *cmd)
+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;
@@ -1269,6 +1267,15 @@ static int NCR5380_select(struct Scsi_Ho
 		   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.
 	 */
@@ -1293,13 +1300,13 @@ static int NCR5380_select(struct Scsi_Ho
 	spin_lock_irq(&hostdata->lock);
 	if (!(NCR5380_read(MODE_REG) & MR_ARBITRATE)) {
 		/* Reselection interrupt */
-		return -1;
+		goto out;
 	}
 	if (err < 0) {
 		NCR5380_write(MODE_REG, MR_BASE);
 		shost_printk(KERN_ERR, instance,
 		             "select: arbitration timeout\n");
-		return -1;
+		goto out;
 	}
 	spin_unlock_irq(&hostdata->lock);
 
@@ -1314,7 +1321,7 @@ static int NCR5380_select(struct Scsi_Ho
 		dprintk(NDEBUG_ARBITRATION, "scsi%d: lost arbitration, deasserting MR_ARBITRATE\n",
 			   HOSTNO);
 		spin_lock_irq(&hostdata->lock);
-		return -1;
+		goto out;
 	}
 
 	/* After/during arbitration, BSY should be asserted.
@@ -1333,7 +1340,7 @@ static int NCR5380_select(struct Scsi_Ho
 		NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
 		dsprintk(NDEBUG_ARBITRATION, instance, "arbitration lost, negating SEL\n");
 		spin_lock_irq(&hostdata->lock);
-		return -1;
+		goto out;
 	}
 
 	/*
@@ -1350,7 +1357,13 @@ static int NCR5380_select(struct Scsi_Ho
 
 	/* NCR5380_reselect() clears MODE_REG after a reselection interrupt */
 	if (!(NCR5380_read(MODE_REG) & MR_ARBITRATE))
-		return -1;
+		goto out;
+
+	if (!hostdata->selecting) {
+		NCR5380_write(MODE_REG, MR_BASE);
+		NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
+		goto out;
+	}
 
 	dprintk(NDEBUG_ARBITRATION, "scsi%d: won arbitration\n", HOSTNO);
 
@@ -1426,17 +1439,21 @@ static int NCR5380_select(struct Scsi_Ho
 			NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
 		printk(KERN_ERR "scsi%d: reselection after won arbitration?\n",
 		       HOSTNO);
-		return -1;
+		goto out;
 	}
 
 	if (err < 0) {
 		spin_lock_irq(&hostdata->lock);
 		NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
-		cmd->result = DID_BAD_TARGET << 16;
-		complete_cmd(instance, cmd);
 		NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
-		dprintk(NDEBUG_SELECTION, "scsi%d: target did not respond within 250ms\n", HOSTNO);
-		return 0;
+		/* 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;
 	}
 
 	/*
@@ -1472,7 +1489,11 @@ static int NCR5380_select(struct Scsi_Ho
 		shost_printk(KERN_ERR, instance, "select: REQ timeout\n");
 		NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
 		NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
-		return -1;
+		goto out;
+	}
+	if (!hostdata->selecting) {
+		do_abort(instance);
+		goto out;
 	}
 
 	dprintk(NDEBUG_SELECTION, "scsi%d: target %d selected, going into MESSAGE OUT phase.\n",
@@ -1508,7 +1529,13 @@ static int NCR5380_select(struct Scsi_Ho
 
 	initialize_SCp(cmd);
 
-	return 0;
+	cmd = NULL;
+
+out:
+	if (!hostdata->selecting)
+		return NULL;
+	hostdata->selecting = NULL;
+	return cmd;
 }
 
 /*
@@ -2572,6 +2599,15 @@ static int NCR5380_abort(struct scsi_cmn
 		cmd->scsi_done(cmd); /* No tag or busy flag to worry about */
 	}
 
+	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);
@@ -2689,6 +2725,8 @@ static int NCR5380_bus_reset(struct scsi
 	 * commands!
 	 */
 
+	hostdata->selecting = NULL;
+
 	if (hostdata->connected)
 		dsprintk(NDEBUG_ABORT, instance, "reset aborted a connected command\n");
 	hostdata->connected = NULL;



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

* [PATCH 61/71] ncr5380: Fix EH during arbitration and selection
@ 2015-11-18  8:35   ` Finn Thain
  0 siblings, 0 replies; 268+ messages in thread
From: Finn Thain @ 2015-11-18  8:35 UTC (permalink / raw)
  To: James E.J. Bottomley, Michael Schmitz, linux-m68k, linux-scsi,
	linux-kernel

[-- Attachment #1: ncr5380-fix-abort-during-select --]
[-- Type: text/plain, Size: 15498 bytes --]

During arbitration and selection, the relevant command is invisible to
exception handlers and can be found only in a pointer on the stack of a
different thread.

When eh_abort_handler can't find a given command, it can't decide whether
that command was completed already or is still in arbitration or selection
phase. But it must return either SUCCESS (e.g. command completed earlier)
or FAILED (could not abort the nexus, try bus reset).

The solution is to make sure all commands belonging to the LLD are always
visible to exception handlers. Add another scsi_cmnd pointer to the
hostdata struct to track the command in arbitration or selection phase.

Replace 'retain_dma_irq' with the new 'selecting' pointer, to bring
atari_NCR5380.c into line with NCR5380.c.

Signed-off-by: Finn Thain <fthain@telegraphics.com.au>

---
 drivers/scsi/NCR5380.c       |   78 +++++++++++++++++++++++++++++----------
 drivers/scsi/NCR5380.h       |    4 +-
 drivers/scsi/atari_NCR5380.c |   84 +++++++++++++++++++++++++++++++------------
 3 files changed, 121 insertions(+), 45 deletions(-)

Index: linux/drivers/scsi/NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/NCR5380.c	2015-11-18 19:34:27.000000000 +1100
+++ linux/drivers/scsi/NCR5380.c	2015-11-18 19:34:29.000000000 +1100
@@ -908,9 +908,9 @@ static void NCR5380_main(struct work_str
 			 * entire unit.
 			 */
 
-			if (!NCR5380_select(instance, cmd)) {
-				dsprintk(NDEBUG_MAIN, instance, "main: selected target %d for command %p\n",
-				         scmd_id(cmd), cmd);
+			cmd = NCR5380_select(instance, cmd);
+			if (!cmd) {
+				dsprintk(NDEBUG_MAIN, instance, "main: select complete\n");
 			} else {
 				dsprintk(NDEBUG_MAIN | NDEBUG_QUEUES, instance,
 				         "main: select failed, returning %p to queue\n", cmd);
@@ -1057,9 +1057,9 @@ static irqreturn_t NCR5380_intr(int irq,
  * Inputs : instance - instantiation of the 5380 driver on which this 
  *      target lives, cmd - SCSI command to execute.
  * 
- * Returns : -1 if selection failed but should be retried.
- *      0 if selection failed and should not be retried.
- *      0 if selection succeeded completely (hostdata->connected == cmd).
+ * 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 
@@ -1077,7 +1077,8 @@ static irqreturn_t NCR5380_intr(int irq,
  *	Locks: caller holds hostdata lock in IRQ mode
  */
  
-static int NCR5380_select(struct Scsi_Host *instance, struct scsi_cmnd *cmd)
+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;
@@ -1088,6 +1089,15 @@ static int NCR5380_select(struct Scsi_Ho
 	NCR5380_dprint(NDEBUG_ARBITRATION, instance);
 	dprintk(NDEBUG_ARBITRATION, "scsi%d : starting arbitration, id = %d\n", instance->host_no, 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.
@@ -1113,13 +1123,13 @@ static int NCR5380_select(struct Scsi_Ho
 	spin_lock_irq(&hostdata->lock);
 	if (!(NCR5380_read(MODE_REG) & MR_ARBITRATE)) {
 		/* Reselection interrupt */
-		return -1;
+		goto out;
 	}
 	if (err < 0) {
 		NCR5380_write(MODE_REG, MR_BASE);
 		shost_printk(KERN_ERR, instance,
 		             "select: arbitration timeout\n");
-		return -1;
+		goto out;
 	}
 	spin_unlock_irq(&hostdata->lock);
 
@@ -1131,7 +1141,7 @@ static int NCR5380_select(struct Scsi_Ho
 		NCR5380_write(MODE_REG, MR_BASE);
 		dprintk(NDEBUG_ARBITRATION, "scsi%d : lost arbitration, deasserting MR_ARBITRATE\n", instance->host_no);
 		spin_lock_irq(&hostdata->lock);
-		return -1;
+		goto out;
 	}
 
 	/* After/during arbitration, BSY should be asserted.
@@ -1150,7 +1160,7 @@ static int NCR5380_select(struct Scsi_Ho
 		NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
 		dsprintk(NDEBUG_ARBITRATION, instance, "arbitration lost, negating SEL\n");
 		spin_lock_irq(&hostdata->lock);
-		return -1;
+		goto out;
 	}
 	/* 
 	 * Again, bus clear + bus settle time is 1.2us, however, this is 
@@ -1166,7 +1176,13 @@ static int NCR5380_select(struct Scsi_Ho
 
 	/* NCR5380_reselect() clears MODE_REG after a reselection interrupt */
 	if (!(NCR5380_read(MODE_REG) & MR_ARBITRATE))
-		return -1;
+		goto out;
+
+	if (!hostdata->selecting) {
+		NCR5380_write(MODE_REG, MR_BASE);
+		NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
+		goto out;
+	}
 
 	dprintk(NDEBUG_ARBITRATION, "scsi%d : won arbitration\n", instance->host_no);
 
@@ -1239,18 +1255,21 @@ static int NCR5380_select(struct Scsi_Ho
 		if (!hostdata->connected)
 			NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
 		printk("scsi%d : reselection after won arbitration?\n", instance->host_no);
-		return -1;
+		goto out;
 	}
 
 	if (err < 0) {
 		spin_lock_irq(&hostdata->lock);
 		NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
-		cmd->result = DID_BAD_TARGET << 16;
-		complete_cmd(instance, cmd);
 		NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
-		dprintk(NDEBUG_SELECTION, "scsi%d : target did not respond within 250ms\n",
-		        instance->host_no);
-		return 0;
+		/* 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;
 	}
 
 	/* 
@@ -1286,7 +1305,11 @@ static int NCR5380_select(struct Scsi_Ho
 		shost_printk(KERN_ERR, instance, "select: REQ timeout\n");
 		NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
 		NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
-		return -1;
+		goto out;
+	}
+	if (!hostdata->selecting) {
+		do_abort(instance);
+		goto out;
 	}
 
 	dprintk(NDEBUG_SELECTION, "scsi%d : target %d selected, going into MESSAGE OUT phase.\n", instance->host_no, cmd->device->id);
@@ -1307,7 +1330,13 @@ static int NCR5380_select(struct Scsi_Ho
 
 	initialize_SCp(cmd);
 
-	return 0;
+	cmd = NULL;
+
+out:
+	if (!hostdata->selecting)
+		return NULL;
+	hostdata->selecting = NULL;
+	return cmd;
 }
 
 /* 
@@ -2359,6 +2388,15 @@ static int NCR5380_abort(struct scsi_cmn
 		cmd->scsi_done(cmd); /* No tag or busy flag to worry about */
 	}
 
+	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);
Index: linux/drivers/scsi/NCR5380.h
===================================================================
--- linux.orig/drivers/scsi/NCR5380.h	2015-11-18 19:34:24.000000000 +1100
+++ linux/drivers/scsi/NCR5380.h	2015-11-18 19:34:29.000000000 +1100
@@ -256,6 +256,7 @@ struct NCR5380_hostdata {
 #endif
 	unsigned char last_message;		/* last message OUT */
 	struct scsi_cmnd *connected;		/* currently connected cmnd */
+	struct scsi_cmnd *selecting;		/* cmnd to be connected */
 	struct list_head unissued;		/* waiting to be issued */
 	struct list_head autosense;		/* priority issue queue */
 	struct list_head disconnected;		/* waiting for reconnect */
@@ -266,7 +267,6 @@ struct NCR5380_hostdata {
 	char info[256];
 	int read_overruns;                /* number of bytes to cut from a
 	                                   * transfer to handle chip overruns */
-	int retain_dma_intr;
 	struct work_struct main_task;
 #ifdef SUPPORT_TAGS
 	struct tag_alloc TagAlloc[8][8];	/* 8 targets and 8 LUNs */
@@ -329,7 +329,7 @@ static irqreturn_t NCR5380_intr(int irq,
 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);
-static int NCR5380_select(struct Scsi_Host *instance, struct scsi_cmnd *cmd);
+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
Index: linux/drivers/scsi/atari_NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/atari_NCR5380.c	2015-11-18 19:34:27.000000000 +1100
+++ linux/drivers/scsi/atari_NCR5380.c	2015-11-18 19:34:29.000000000 +1100
@@ -882,7 +882,7 @@ static inline void maybe_release_dma_irq
 	    list_empty(&hostdata->unissued) &&
 	    list_empty(&hostdata->autosense) &&
 	    !hostdata->connected &&
-	    !hostdata->retain_dma_intr)
+	    !hostdata->selecting)
 		NCR5380_release_dma_irq(instance);
 }
 
@@ -1003,14 +1003,11 @@ static void NCR5380_main(struct work_str
 #ifdef SUPPORT_TAGS
 			cmd_get_tag(cmd, cmd->cmnd[0] != REQUEST_SENSE);
 #endif
-			hostdata->retain_dma_intr++;
-			if (!NCR5380_select(instance, cmd)) {
-				dsprintk(NDEBUG_MAIN, instance, "main: selected target %d for command %p\n",
-				         scmd_id(cmd), cmd);
-				hostdata->retain_dma_intr--;
+			cmd = NCR5380_select(instance, cmd);
+			if (!cmd) {
+				dsprintk(NDEBUG_MAIN, instance, "main: select complete\n");
 				maybe_release_dma_irq(instance);
 			} else {
-				hostdata->retain_dma_intr--;
 				dsprintk(NDEBUG_MAIN | NDEBUG_QUEUES, instance,
 				         "main: select failed, returning %p to queue\n", cmd);
 				requeue_cmd(instance, cmd);
@@ -1238,9 +1235,9 @@ static irqreturn_t NCR5380_intr(int irq,
  * Inputs : instance - instantiation of the 5380 driver on which this
  *	target lives, cmd - SCSI command to execute.
  *
- * Returns : -1 if selection failed but should be retried.
- *      0 if selection failed and should not be retried.
- *      0 if selection succeeded completely (hostdata->connected == cmd).
+ * 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
@@ -1256,7 +1253,8 @@ static irqreturn_t NCR5380_intr(int irq,
  *		cmd->result host byte set to DID_BAD_TARGET.
  */
 
-static int NCR5380_select(struct Scsi_Host *instance, struct scsi_cmnd *cmd)
+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;
@@ -1269,6 +1267,15 @@ static int NCR5380_select(struct Scsi_Ho
 		   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.
 	 */
@@ -1293,13 +1300,13 @@ static int NCR5380_select(struct Scsi_Ho
 	spin_lock_irq(&hostdata->lock);
 	if (!(NCR5380_read(MODE_REG) & MR_ARBITRATE)) {
 		/* Reselection interrupt */
-		return -1;
+		goto out;
 	}
 	if (err < 0) {
 		NCR5380_write(MODE_REG, MR_BASE);
 		shost_printk(KERN_ERR, instance,
 		             "select: arbitration timeout\n");
-		return -1;
+		goto out;
 	}
 	spin_unlock_irq(&hostdata->lock);
 
@@ -1314,7 +1321,7 @@ static int NCR5380_select(struct Scsi_Ho
 		dprintk(NDEBUG_ARBITRATION, "scsi%d: lost arbitration, deasserting MR_ARBITRATE\n",
 			   HOSTNO);
 		spin_lock_irq(&hostdata->lock);
-		return -1;
+		goto out;
 	}
 
 	/* After/during arbitration, BSY should be asserted.
@@ -1333,7 +1340,7 @@ static int NCR5380_select(struct Scsi_Ho
 		NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
 		dsprintk(NDEBUG_ARBITRATION, instance, "arbitration lost, negating SEL\n");
 		spin_lock_irq(&hostdata->lock);
-		return -1;
+		goto out;
 	}
 
 	/*
@@ -1350,7 +1357,13 @@ static int NCR5380_select(struct Scsi_Ho
 
 	/* NCR5380_reselect() clears MODE_REG after a reselection interrupt */
 	if (!(NCR5380_read(MODE_REG) & MR_ARBITRATE))
-		return -1;
+		goto out;
+
+	if (!hostdata->selecting) {
+		NCR5380_write(MODE_REG, MR_BASE);
+		NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
+		goto out;
+	}
 
 	dprintk(NDEBUG_ARBITRATION, "scsi%d: won arbitration\n", HOSTNO);
 
@@ -1426,17 +1439,21 @@ static int NCR5380_select(struct Scsi_Ho
 			NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
 		printk(KERN_ERR "scsi%d: reselection after won arbitration?\n",
 		       HOSTNO);
-		return -1;
+		goto out;
 	}
 
 	if (err < 0) {
 		spin_lock_irq(&hostdata->lock);
 		NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
-		cmd->result = DID_BAD_TARGET << 16;
-		complete_cmd(instance, cmd);
 		NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
-		dprintk(NDEBUG_SELECTION, "scsi%d: target did not respond within 250ms\n", HOSTNO);
-		return 0;
+		/* 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;
 	}
 
 	/*
@@ -1472,7 +1489,11 @@ static int NCR5380_select(struct Scsi_Ho
 		shost_printk(KERN_ERR, instance, "select: REQ timeout\n");
 		NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
 		NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
-		return -1;
+		goto out;
+	}
+	if (!hostdata->selecting) {
+		do_abort(instance);
+		goto out;
 	}
 
 	dprintk(NDEBUG_SELECTION, "scsi%d: target %d selected, going into MESSAGE OUT phase.\n",
@@ -1508,7 +1529,13 @@ static int NCR5380_select(struct Scsi_Ho
 
 	initialize_SCp(cmd);
 
-	return 0;
+	cmd = NULL;
+
+out:
+	if (!hostdata->selecting)
+		return NULL;
+	hostdata->selecting = NULL;
+	return cmd;
 }
 
 /*
@@ -2572,6 +2599,15 @@ static int NCR5380_abort(struct scsi_cmn
 		cmd->scsi_done(cmd); /* No tag or busy flag to worry about */
 	}
 
+	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);
@@ -2689,6 +2725,8 @@ static int NCR5380_bus_reset(struct scsi
 	 * commands!
 	 */
 
+	hostdata->selecting = NULL;
+
 	if (hostdata->connected)
 		dsprintk(NDEBUG_ABORT, instance, "reset aborted a connected command\n");
 	hostdata->connected = NULL;

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

* [PATCH 62/71] ncr5380: Implement new eh_bus_reset_handler
  2015-11-18  8:34 ` Finn Thain
@ 2015-11-18  8:35   ` Finn Thain
  -1 siblings, 0 replies; 268+ messages in thread
From: Finn Thain @ 2015-11-18  8:35 UTC (permalink / raw)
  To: James E.J. Bottomley, Michael Schmitz, linux-m68k, linux-scsi,
	linux-kernel

[-- Attachment #1: ncr5380-new-eh_bus_reset_handler --]
[-- Type: text/plain, Size: 5030 bytes --]

NCR5380.c lacks a sane eh_bus_reset_handler. The atari_NCR5380.c code is
much better but it should not throw out the issue queue (that would be
a host reset) and it neglects to set the result code for commands that it
throws out. Fix these bugs and keep the two core drivers in sync.

Signed-off-by: Finn Thain <fthain@telegraphics.com.au>

---
 drivers/scsi/NCR5380.c       |   50 ++++++++++++++++++++++++++++++++++++++++++-
 drivers/scsi/atari_NCR5380.c |   39 +++++++++++++++++++--------------
 2 files changed, 72 insertions(+), 17 deletions(-)

Index: linux/drivers/scsi/atari_NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/atari_NCR5380.c	2015-11-18 19:34:29.000000000 +1100
+++ linux/drivers/scsi/atari_NCR5380.c	2015-11-18 19:34:30.000000000 +1100
@@ -2703,11 +2703,12 @@ static int NCR5380_bus_reset(struct scsi
 	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, "performing bus reset\n");
+	scmd_printk(KERN_INFO, cmd, __func__);
 #endif
 	NCR5380_dprint(NDEBUG_ANY, instance);
 	NCR5380_dprint_phase(NDEBUG_ANY, instance);
@@ -2727,27 +2728,32 @@ static int NCR5380_bus_reset(struct scsi
 
 	hostdata->selecting = NULL;
 
-	if (hostdata->connected)
-		dsprintk(NDEBUG_ABORT, instance, "reset aborted a connected command\n");
-	hostdata->connected = 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);
+	}
+
+	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);
+	}
+
+	if (hostdata->connected) {
+		set_host_byte(hostdata->connected, DID_RESET);
+		complete_cmd(instance, hostdata->connected);
+		hostdata->connected = NULL;
+	}
 
 	if (hostdata->sensing) {
+		set_host_byte(hostdata->connected, DID_RESET);
 		complete_cmd(instance, hostdata->sensing);
 		hostdata->sensing = NULL;
 	}
 
-	if (!list_empty(&hostdata->autosense))
-		dsprintk(NDEBUG_ABORT, instance, "reset aborted autosense list\n");
-	INIT_LIST_HEAD(&hostdata->autosense);
-
-	if (!list_empty(&hostdata->unissued))
-		dsprintk(NDEBUG_ABORT, instance, "reset aborted unissued list\n");
-	INIT_LIST_HEAD(&hostdata->unissued);
-
-	if (!list_empty(&hostdata->disconnected))
-		dsprintk(NDEBUG_ABORT, instance, "reset aborted disconnected list\n");
-	INIT_LIST_HEAD(&hostdata->disconnected);
-
 #ifdef SUPPORT_TAGS
 	free_all_tags(hostdata);
 #endif
@@ -2757,6 +2763,7 @@ static int NCR5380_bus_reset(struct scsi
 	hostdata->dma_len = 0;
 #endif
 
+	queue_work(hostdata->work_q, &hostdata->main_task);
 	maybe_release_dma_irq(instance);
 	spin_unlock_irqrestore(&hostdata->lock, flags);
 
Index: linux/drivers/scsi/NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/NCR5380.c	2015-11-18 19:34:29.000000000 +1100
+++ linux/drivers/scsi/NCR5380.c	2015-11-18 19:34:30.000000000 +1100
@@ -2489,18 +2489,66 @@ static int NCR5380_bus_reset(struct scsi
 {
 	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, "performing bus reset\n");
+	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!
+	 */
+
+	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);
+	}
+
+	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);
+	}
+
+	if (hostdata->connected) {
+		set_host_byte(hostdata->connected, DID_RESET);
+		complete_cmd(instance, hostdata->connected);
+		hostdata->connected = NULL;
+	}
+
+	if (hostdata->sensing) {
+		set_host_byte(hostdata->connected, DID_RESET);
+		complete_cmd(instance, hostdata->sensing);
+		hostdata->sensing = NULL;
+	}
+
+	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);
 
 	return SUCCESS;



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

* [PATCH 62/71] ncr5380: Implement new eh_bus_reset_handler
@ 2015-11-18  8:35   ` Finn Thain
  0 siblings, 0 replies; 268+ messages in thread
From: Finn Thain @ 2015-11-18  8:35 UTC (permalink / raw)
  To: James E.J. Bottomley, Michael Schmitz, linux-m68k, linux-scsi,
	linux-kernel

[-- Attachment #1: ncr5380-new-eh_bus_reset_handler --]
[-- Type: text/plain, Size: 5028 bytes --]

NCR5380.c lacks a sane eh_bus_reset_handler. The atari_NCR5380.c code is
much better but it should not throw out the issue queue (that would be
a host reset) and it neglects to set the result code for commands that it
throws out. Fix these bugs and keep the two core drivers in sync.

Signed-off-by: Finn Thain <fthain@telegraphics.com.au>

---
 drivers/scsi/NCR5380.c       |   50 ++++++++++++++++++++++++++++++++++++++++++-
 drivers/scsi/atari_NCR5380.c |   39 +++++++++++++++++++--------------
 2 files changed, 72 insertions(+), 17 deletions(-)

Index: linux/drivers/scsi/atari_NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/atari_NCR5380.c	2015-11-18 19:34:29.000000000 +1100
+++ linux/drivers/scsi/atari_NCR5380.c	2015-11-18 19:34:30.000000000 +1100
@@ -2703,11 +2703,12 @@ static int NCR5380_bus_reset(struct scsi
 	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, "performing bus reset\n");
+	scmd_printk(KERN_INFO, cmd, __func__);
 #endif
 	NCR5380_dprint(NDEBUG_ANY, instance);
 	NCR5380_dprint_phase(NDEBUG_ANY, instance);
@@ -2727,27 +2728,32 @@ static int NCR5380_bus_reset(struct scsi
 
 	hostdata->selecting = NULL;
 
-	if (hostdata->connected)
-		dsprintk(NDEBUG_ABORT, instance, "reset aborted a connected command\n");
-	hostdata->connected = 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);
+	}
+
+	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);
+	}
+
+	if (hostdata->connected) {
+		set_host_byte(hostdata->connected, DID_RESET);
+		complete_cmd(instance, hostdata->connected);
+		hostdata->connected = NULL;
+	}
 
 	if (hostdata->sensing) {
+		set_host_byte(hostdata->connected, DID_RESET);
 		complete_cmd(instance, hostdata->sensing);
 		hostdata->sensing = NULL;
 	}
 
-	if (!list_empty(&hostdata->autosense))
-		dsprintk(NDEBUG_ABORT, instance, "reset aborted autosense list\n");
-	INIT_LIST_HEAD(&hostdata->autosense);
-
-	if (!list_empty(&hostdata->unissued))
-		dsprintk(NDEBUG_ABORT, instance, "reset aborted unissued list\n");
-	INIT_LIST_HEAD(&hostdata->unissued);
-
-	if (!list_empty(&hostdata->disconnected))
-		dsprintk(NDEBUG_ABORT, instance, "reset aborted disconnected list\n");
-	INIT_LIST_HEAD(&hostdata->disconnected);
-
 #ifdef SUPPORT_TAGS
 	free_all_tags(hostdata);
 #endif
@@ -2757,6 +2763,7 @@ static int NCR5380_bus_reset(struct scsi
 	hostdata->dma_len = 0;
 #endif
 
+	queue_work(hostdata->work_q, &hostdata->main_task);
 	maybe_release_dma_irq(instance);
 	spin_unlock_irqrestore(&hostdata->lock, flags);
 
Index: linux/drivers/scsi/NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/NCR5380.c	2015-11-18 19:34:29.000000000 +1100
+++ linux/drivers/scsi/NCR5380.c	2015-11-18 19:34:30.000000000 +1100
@@ -2489,18 +2489,66 @@ static int NCR5380_bus_reset(struct scsi
 {
 	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, "performing bus reset\n");
+	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!
+	 */
+
+	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);
+	}
+
+	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);
+	}
+
+	if (hostdata->connected) {
+		set_host_byte(hostdata->connected, DID_RESET);
+		complete_cmd(instance, hostdata->connected);
+		hostdata->connected = NULL;
+	}
+
+	if (hostdata->sensing) {
+		set_host_byte(hostdata->connected, DID_RESET);
+		complete_cmd(instance, hostdata->sensing);
+		hostdata->sensing = NULL;
+	}
+
+	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);
 
 	return SUCCESS;

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

* [PATCH 63/71] atari_NCR5380: Remove HOSTNO macro from printk() and seq_printf() calls
  2015-11-18  8:34 ` Finn Thain
@ 2015-11-18  8:35   ` Finn Thain
  -1 siblings, 0 replies; 268+ messages in thread
From: Finn Thain @ 2015-11-18  8:35 UTC (permalink / raw)
  To: James E.J. Bottomley, Michael Schmitz, linux-m68k, linux-scsi,
	linux-kernel

[-- Attachment #1: atari_NCR5380-remove-HOSTNO-printk --]
[-- Type: text/plain, Size: 6111 bytes --]

Remove the HOSTNO macro that is peculiar to atari_NCR5380.c and
contributes to the problem of divergence of the NCR5380 core drivers.
Keep NCR5380.c in sync.

Signed-off-by: Finn Thain <fthain@telegraphics.com.au>

---
 drivers/scsi/NCR5380.c       |   17 +++++++++--------
 drivers/scsi/atari_NCR5380.c |   23 +++++++++--------------
 2 files changed, 18 insertions(+), 22 deletions(-)

Index: linux/drivers/scsi/atari_NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/atari_NCR5380.c	2015-11-18 19:34:30.000000000 +1100
+++ linux/drivers/scsi/atari_NCR5380.c	2015-11-18 19:34:32.000000000 +1100
@@ -580,12 +580,12 @@ static void NCR5380_print_phase(struct S
 
 	status = NCR5380_read(STATUS_REG);
 	if (!(status & SR_REQ))
-		printk(KERN_DEBUG "scsi%d: REQ not asserted, phase unknown.\n", HOSTNO);
+		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)
 			;
-		printk(KERN_DEBUG "scsi%d: phase %s\n", HOSTNO, phases[i].name);
+		shost_printk(KERN_DEBUG, instance, "phase %s\n", phases[i].name);
 	}
 }
 
@@ -1437,8 +1437,7 @@ static struct scsi_cmnd *NCR5380_select(
 		NCR5380_reselect(instance);
 		if (!hostdata->connected)
 			NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
-		printk(KERN_ERR "scsi%d: reselection after won arbitration?\n",
-		       HOSTNO);
+		shost_printk(KERN_ERR, instance, "reselection after won arbitration?\n");
 		goto out;
 	}
 
@@ -1966,8 +1965,7 @@ static void NCR5380_information_transfer
 			switch (phase) {
 			case PHASE_DATAOUT:
 #if (NDEBUG & NDEBUG_NO_DATAOUT)
-				printk("scsi%d: NDEBUG_NO_DATAOUT set, attempted DATAOUT "
-				       "aborted\n", HOSTNO);
+				shost_printk(KERN_DEBUG, instance, "NDEBUG_NO_DATAOUT set, attempted DATAOUT aborted\n");
 				sink = 1;
 				do_abort(instance);
 				cmd->result = DID_ERROR << 16;
@@ -2228,13 +2226,11 @@ static void NCR5380_information_transfer
 							tmp = 0;
 						}
 					} else if (len) {
-						printk(KERN_NOTICE "scsi%d: error receiving "
-						       "extended message\n", HOSTNO);
+						shost_printk(KERN_ERR, instance, "error receiving extended message\n");
 						tmp = 0;
 					} else {
-						printk(KERN_NOTICE "scsi%d: extended message "
-							   "code %02x length %d is too long\n",
-							   HOSTNO, extended_msg[2], extended_msg[1]);
+						shost_printk(KERN_NOTICE, instance, "extended message code %02x length %d is too long\n",
+						             extended_msg[2], extended_msg[1]);
 						tmp = 0;
 					}
 
@@ -2250,8 +2246,7 @@ static void NCR5380_information_transfer
 					 */
 				default:
 					if (!tmp) {
-						printk(KERN_INFO "scsi%d: rejecting message ",
-						       instance->host_no);
+						shost_printk(KERN_ERR, instance, "rejecting message ");
 						spi_print_msg(extended_msg);
 						printk("\n");
 					} else if (tmp != EXTENDED_MESSAGE)
@@ -2300,7 +2295,7 @@ static void NCR5380_information_transfer
 				cmd->SCp.Status = tmp;
 				break;
 			default:
-				printk("scsi%d: unknown phase\n", HOSTNO);
+				shost_printk(KERN_ERR, instance, "unknown phase\n");
 				NCR5380_dprint(NDEBUG_ANY, instance);
 			} /* switch(phase) */
 		} else {
Index: linux/drivers/scsi/NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/NCR5380.c	2015-11-18 19:34:30.000000000 +1100
+++ linux/drivers/scsi/NCR5380.c	2015-11-18 19:34:32.000000000 +1100
@@ -429,10 +429,10 @@ static void NCR5380_print_phase(struct S
 
 	status = NCR5380_read(STATUS_REG);
 	if (!(status & SR_REQ))
-		printk("scsi%d : REQ not asserted, phase unknown.\n", instance->host_no);
+		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);
-		printk("scsi%d : phase %s\n", instance->host_no, phases[i].name);
+		shost_printk(KERN_DEBUG, instance, "phase %s\n", phases[i].name);
 	}
 }
 #endif
@@ -1254,7 +1254,7 @@ static struct scsi_cmnd *NCR5380_select(
 		NCR5380_reselect(instance);
 		if (!hostdata->connected)
 			NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
-		printk("scsi%d : reselection after won arbitration?\n", instance->host_no);
+		shost_printk(KERN_ERR, instance, "reselection after won arbitration?\n");
 		goto out;
 	}
 
@@ -1859,7 +1859,7 @@ static void NCR5380_information_transfer
 			switch (phase) {
 			case PHASE_DATAOUT:
 #if (NDEBUG & NDEBUG_NO_DATAOUT)
-				printk("scsi%d : NDEBUG_NO_DATAOUT set, attempted DATAOUT aborted\n", instance->host_no);
+				shost_printk(KERN_DEBUG, instance, "NDEBUG_NO_DATAOUT set, attempted DATAOUT aborted\n");
 				sink = 1;
 				do_abort(instance);
 				cmd->result = DID_ERROR << 16;
@@ -2060,10 +2060,11 @@ static void NCR5380_information_transfer
 							tmp = 0;
 						}
 					} else if (len) {
-						printk("scsi%d: error receiving extended message\n", instance->host_no);
+						shost_printk(KERN_ERR, instance, "error receiving extended message\n");
 						tmp = 0;
 					} else {
-						printk("scsi%d: extended message code %02x length %d is too long\n", instance->host_no, extended_msg[2], extended_msg[1]);
+						shost_printk(KERN_NOTICE, instance, "extended message code %02x length %d is too long\n",
+						             extended_msg[2], extended_msg[1]);
 						tmp = 0;
 					}
 
@@ -2079,7 +2080,7 @@ static void NCR5380_information_transfer
 					 */
 				default:
 					if (!tmp) {
-						printk("scsi%d: rejecting message ", instance->host_no);
+						shost_printk(KERN_ERR, instance, "rejecting message ");
 						spi_print_msg(extended_msg);
 						printk("\n");
 					} else if (tmp != EXTENDED_MESSAGE)
@@ -2125,7 +2126,7 @@ static void NCR5380_information_transfer
 				cmd->SCp.Status = tmp;
 				break;
 			default:
-				printk("scsi%d : unknown phase\n", instance->host_no);
+				shost_printk(KERN_ERR, instance, "unknown phase\n");
 				NCR5380_dprint(NDEBUG_ANY, instance);
 			}	/* switch(phase) */
 		} else {



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

* [PATCH 63/71] atari_NCR5380: Remove HOSTNO macro from printk() and seq_printf() calls
@ 2015-11-18  8:35   ` Finn Thain
  0 siblings, 0 replies; 268+ messages in thread
From: Finn Thain @ 2015-11-18  8:35 UTC (permalink / raw)
  To: James E.J. Bottomley, Michael Schmitz, linux-m68k, linux-scsi,
	linux-kernel

[-- Attachment #1: atari_NCR5380-remove-HOSTNO-printk --]
[-- Type: text/plain, Size: 6109 bytes --]

Remove the HOSTNO macro that is peculiar to atari_NCR5380.c and
contributes to the problem of divergence of the NCR5380 core drivers.
Keep NCR5380.c in sync.

Signed-off-by: Finn Thain <fthain@telegraphics.com.au>

---
 drivers/scsi/NCR5380.c       |   17 +++++++++--------
 drivers/scsi/atari_NCR5380.c |   23 +++++++++--------------
 2 files changed, 18 insertions(+), 22 deletions(-)

Index: linux/drivers/scsi/atari_NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/atari_NCR5380.c	2015-11-18 19:34:30.000000000 +1100
+++ linux/drivers/scsi/atari_NCR5380.c	2015-11-18 19:34:32.000000000 +1100
@@ -580,12 +580,12 @@ static void NCR5380_print_phase(struct S
 
 	status = NCR5380_read(STATUS_REG);
 	if (!(status & SR_REQ))
-		printk(KERN_DEBUG "scsi%d: REQ not asserted, phase unknown.\n", HOSTNO);
+		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)
 			;
-		printk(KERN_DEBUG "scsi%d: phase %s\n", HOSTNO, phases[i].name);
+		shost_printk(KERN_DEBUG, instance, "phase %s\n", phases[i].name);
 	}
 }
 
@@ -1437,8 +1437,7 @@ static struct scsi_cmnd *NCR5380_select(
 		NCR5380_reselect(instance);
 		if (!hostdata->connected)
 			NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
-		printk(KERN_ERR "scsi%d: reselection after won arbitration?\n",
-		       HOSTNO);
+		shost_printk(KERN_ERR, instance, "reselection after won arbitration?\n");
 		goto out;
 	}
 
@@ -1966,8 +1965,7 @@ static void NCR5380_information_transfer
 			switch (phase) {
 			case PHASE_DATAOUT:
 #if (NDEBUG & NDEBUG_NO_DATAOUT)
-				printk("scsi%d: NDEBUG_NO_DATAOUT set, attempted DATAOUT "
-				       "aborted\n", HOSTNO);
+				shost_printk(KERN_DEBUG, instance, "NDEBUG_NO_DATAOUT set, attempted DATAOUT aborted\n");
 				sink = 1;
 				do_abort(instance);
 				cmd->result = DID_ERROR << 16;
@@ -2228,13 +2226,11 @@ static void NCR5380_information_transfer
 							tmp = 0;
 						}
 					} else if (len) {
-						printk(KERN_NOTICE "scsi%d: error receiving "
-						       "extended message\n", HOSTNO);
+						shost_printk(KERN_ERR, instance, "error receiving extended message\n");
 						tmp = 0;
 					} else {
-						printk(KERN_NOTICE "scsi%d: extended message "
-							   "code %02x length %d is too long\n",
-							   HOSTNO, extended_msg[2], extended_msg[1]);
+						shost_printk(KERN_NOTICE, instance, "extended message code %02x length %d is too long\n",
+						             extended_msg[2], extended_msg[1]);
 						tmp = 0;
 					}
 
@@ -2250,8 +2246,7 @@ static void NCR5380_information_transfer
 					 */
 				default:
 					if (!tmp) {
-						printk(KERN_INFO "scsi%d: rejecting message ",
-						       instance->host_no);
+						shost_printk(KERN_ERR, instance, "rejecting message ");
 						spi_print_msg(extended_msg);
 						printk("\n");
 					} else if (tmp != EXTENDED_MESSAGE)
@@ -2300,7 +2295,7 @@ static void NCR5380_information_transfer
 				cmd->SCp.Status = tmp;
 				break;
 			default:
-				printk("scsi%d: unknown phase\n", HOSTNO);
+				shost_printk(KERN_ERR, instance, "unknown phase\n");
 				NCR5380_dprint(NDEBUG_ANY, instance);
 			} /* switch(phase) */
 		} else {
Index: linux/drivers/scsi/NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/NCR5380.c	2015-11-18 19:34:30.000000000 +1100
+++ linux/drivers/scsi/NCR5380.c	2015-11-18 19:34:32.000000000 +1100
@@ -429,10 +429,10 @@ static void NCR5380_print_phase(struct S
 
 	status = NCR5380_read(STATUS_REG);
 	if (!(status & SR_REQ))
-		printk("scsi%d : REQ not asserted, phase unknown.\n", instance->host_no);
+		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);
-		printk("scsi%d : phase %s\n", instance->host_no, phases[i].name);
+		shost_printk(KERN_DEBUG, instance, "phase %s\n", phases[i].name);
 	}
 }
 #endif
@@ -1254,7 +1254,7 @@ static struct scsi_cmnd *NCR5380_select(
 		NCR5380_reselect(instance);
 		if (!hostdata->connected)
 			NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
-		printk("scsi%d : reselection after won arbitration?\n", instance->host_no);
+		shost_printk(KERN_ERR, instance, "reselection after won arbitration?\n");
 		goto out;
 	}
 
@@ -1859,7 +1859,7 @@ static void NCR5380_information_transfer
 			switch (phase) {
 			case PHASE_DATAOUT:
 #if (NDEBUG & NDEBUG_NO_DATAOUT)
-				printk("scsi%d : NDEBUG_NO_DATAOUT set, attempted DATAOUT aborted\n", instance->host_no);
+				shost_printk(KERN_DEBUG, instance, "NDEBUG_NO_DATAOUT set, attempted DATAOUT aborted\n");
 				sink = 1;
 				do_abort(instance);
 				cmd->result = DID_ERROR << 16;
@@ -2060,10 +2060,11 @@ static void NCR5380_information_transfer
 							tmp = 0;
 						}
 					} else if (len) {
-						printk("scsi%d: error receiving extended message\n", instance->host_no);
+						shost_printk(KERN_ERR, instance, "error receiving extended message\n");
 						tmp = 0;
 					} else {
-						printk("scsi%d: extended message code %02x length %d is too long\n", instance->host_no, extended_msg[2], extended_msg[1]);
+						shost_printk(KERN_NOTICE, instance, "extended message code %02x length %d is too long\n",
+						             extended_msg[2], extended_msg[1]);
 						tmp = 0;
 					}
 
@@ -2079,7 +2080,7 @@ static void NCR5380_information_transfer
 					 */
 				default:
 					if (!tmp) {
-						printk("scsi%d: rejecting message ", instance->host_no);
+						shost_printk(KERN_ERR, instance, "rejecting message ");
 						spi_print_msg(extended_msg);
 						printk("\n");
 					} else if (tmp != EXTENDED_MESSAGE)
@@ -2125,7 +2126,7 @@ static void NCR5380_information_transfer
 				cmd->SCp.Status = tmp;
 				break;
 			default:
-				printk("scsi%d : unknown phase\n", instance->host_no);
+				shost_printk(KERN_ERR, instance, "unknown phase\n");
 				NCR5380_dprint(NDEBUG_ANY, instance);
 			}	/* switch(phase) */
 		} else {

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

* [PATCH 64/71] atari_NCR5380: Eliminate HOSTNO macro
  2015-11-18  8:34 ` Finn Thain
@ 2015-11-18  8:35   ` Finn Thain
  -1 siblings, 0 replies; 268+ messages in thread
From: Finn Thain @ 2015-11-18  8:35 UTC (permalink / raw)
  To: James E.J. Bottomley, Michael Schmitz, linux-m68k, linux-scsi,
	linux-kernel

[-- Attachment #1: atari_NCR5380-remove-HOSTNO-dprintk --]
[-- Type: text/plain, Size: 22253 bytes --]

Keep the two core driver forks in sync.

Signed-off-by: Finn Thain <fthain@telegraphics.com.au>

---
 drivers/scsi/NCR5380.c       |   71 +++++++++++++++--------------
 drivers/scsi/atari_NCR5380.c |  102 +++++++++++++++++++------------------------
 2 files changed, 84 insertions(+), 89 deletions(-)

Index: linux/drivers/scsi/atari_NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/atari_NCR5380.c	2015-11-18 19:34:32.000000000 +1100
+++ linux/drivers/scsi/atari_NCR5380.c	2015-11-18 19:34:33.000000000 +1100
@@ -175,8 +175,6 @@
  * possible) function may be used.
  */
 
-#define	HOSTNO		instance->host_no
-
 static int do_abort(struct Scsi_Host *);
 static void do_reset(struct Scsi_Host *);
 
@@ -1021,10 +1019,8 @@ static void NCR5380_main(struct work_str
 		    && !hostdata->dma_len
 #endif
 		    ) {
-			dprintk(NDEBUG_MAIN, "scsi%d: main: performing information transfer\n",
-				    HOSTNO);
+			dsprintk(NDEBUG_MAIN, instance, "main: performing information transfer\n");
 			NCR5380_information_transfer(instance);
-			dprintk(NDEBUG_MAIN, "scsi%d: main: done set false\n", HOSTNO);
 			done = 0;
 		}
 	} while (!done);
@@ -1061,7 +1057,7 @@ static void NCR5380_dma_complete(struct
 			    (BASR_PHASE_MATCH|BASR_ACK)) {
 				saved_data = NCR5380_read(INPUT_DATA_REG);
 				overrun = 1;
-				dprintk(NDEBUG_DMA, "scsi%d: read overrun handled\n", HOSTNO);
+				dsprintk(NDEBUG_DMA, instance, "read overrun handled\n");
 			}
 		}
 	}
@@ -1166,8 +1162,8 @@ static irqreturn_t NCR5380_intr(int irq,
 		unsigned char mr = NCR5380_read(MODE_REG);
 		unsigned char sr = NCR5380_read(STATUS_REG);
 
-		dprintk(NDEBUG_INTR, "scsi%d: IRQ %d, BASR 0x%02x, SR 0x%02x, MR 0x%02x\n",
-		        HOSTNO, irq, basr, sr, mr);
+		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)) {
@@ -1176,7 +1172,7 @@ static irqreturn_t NCR5380_intr(int irq,
 			 * for End of DMA errata need to happen in DMA Mode.
 			 */
 
-			dprintk(NDEBUG_INTR, "scsi%d: interrupt in DMA mode\n", HOSTNO);
+			dsprintk(NDEBUG_INTR, instance, "interrupt in DMA mode\n");
 
 			if (hostdata->connected) {
 				NCR5380_dma_complete(instance);
@@ -1193,8 +1189,7 @@ static irqreturn_t NCR5380_intr(int irq,
 			NCR5380_write(SELECT_ENABLE_REG, 0);
 			NCR5380_read(RESET_PARITY_INTERRUPT_REG);
 
-			dprintk(NDEBUG_INTR, "scsi%d: interrupt with SEL and IO\n",
-			        HOSTNO);
+			dsprintk(NDEBUG_INTR, instance, "interrupt with SEL and IO\n");
 
 			if (!hostdata->connected) {
 				NCR5380_reselect(instance);
@@ -1206,7 +1201,7 @@ static irqreturn_t NCR5380_intr(int irq,
 			/* Probably Bus Reset */
 			NCR5380_read(RESET_PARITY_INTERRUPT_REG);
 
-			dprintk(NDEBUG_INTR, "scsi%d: unknown interrupt\n", HOSTNO);
+			dsprintk(NDEBUG_INTR, instance, "unknown interrupt\n");
 #ifdef SUN3_SCSI_VME
 			dregs->csr |= CSR_DMA_ENABLE;
 #endif
@@ -1263,8 +1258,8 @@ static struct scsi_cmnd *NCR5380_select(
 	int err;
 
 	NCR5380_dprint(NDEBUG_ARBITRATION, instance);
-	dprintk(NDEBUG_ARBITRATION, "scsi%d: starting arbitration, id = %d\n", HOSTNO,
-		   instance->this_id);
+	dsprintk(NDEBUG_ARBITRATION, instance, "starting arbitration, id = %d\n",
+	         instance->this_id);
 
 	/*
 	 * Arbitration and selection phases are slow and involve dropping the
@@ -1318,8 +1313,7 @@ static struct scsi_cmnd *NCR5380_select(
 	    (NCR5380_read(CURRENT_SCSI_DATA_REG) & hostdata->id_higher_mask) ||
 	    (NCR5380_read(INITIATOR_COMMAND_REG) & ICR_ARBITRATION_LOST)) {
 		NCR5380_write(MODE_REG, MR_BASE);
-		dprintk(NDEBUG_ARBITRATION, "scsi%d: lost arbitration, deasserting MR_ARBITRATE\n",
-			   HOSTNO);
+		dsprintk(NDEBUG_ARBITRATION, instance, "lost arbitration, deasserting MR_ARBITRATE\n");
 		spin_lock_irq(&hostdata->lock);
 		goto out;
 	}
@@ -1365,7 +1359,7 @@ static struct scsi_cmnd *NCR5380_select(
 		goto out;
 	}
 
-	dprintk(NDEBUG_ARBITRATION, "scsi%d: won arbitration\n", HOSTNO);
+	dsprintk(NDEBUG_ARBITRATION, instance, "won arbitration\n");
 
 	/*
 	 * Now that we have won arbitration, start Selection process, asserting
@@ -1421,7 +1415,7 @@ static struct scsi_cmnd *NCR5380_select(
 
 	udelay(1);
 
-	dprintk(NDEBUG_SELECTION, "scsi%d: selecting target %d\n", HOSTNO, cmd->device->id);
+	dsprintk(NDEBUG_SELECTION, instance, "selecting target %d\n", scmd_id(cmd));
 
 	/*
 	 * The SCSI specification calls for a 250 ms timeout for the actual
@@ -1495,8 +1489,8 @@ static struct scsi_cmnd *NCR5380_select(
 		goto out;
 	}
 
-	dprintk(NDEBUG_SELECTION, "scsi%d: target %d selected, going into MESSAGE OUT phase.\n",
-		   HOSTNO, cmd->device->id);
+	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
@@ -1515,7 +1509,7 @@ static struct scsi_cmnd *NCR5380_select(
 	data = tmp;
 	phase = PHASE_MSGOUT;
 	NCR5380_transfer_pio(instance, &phase, &len, &data);
-	dprintk(NDEBUG_SELECTION, "scsi%d: nexus established.\n", HOSTNO);
+	dsprintk(NDEBUG_SELECTION, instance, "nexus established.\n");
 	/* XXX need to handle errors here */
 
 	hostdata->connected = cmd;
@@ -1587,11 +1581,11 @@ static int NCR5380_transfer_pio(struct S
 		if (NCR5380_poll_politely(instance, STATUS_REG, SR_REQ, SR_REQ, HZ) < 0)
 			break;
 
-		dprintk(NDEBUG_HANDSHAKE, "scsi%d: REQ detected\n", HOSTNO);
+		dsprintk(NDEBUG_HANDSHAKE, instance, "REQ asserted\n");
 
 		/* Check for phase mismatch */
 		if ((NCR5380_read(STATUS_REG) & PHASE_MASK) != p) {
-			dprintk(NDEBUG_PIO, "scsi%d: phase mismatch\n", HOSTNO);
+			dsprintk(NDEBUG_PIO, instance, "phase mismatch\n");
 			NCR5380_dprint_phase(NDEBUG_PIO, instance);
 			break;
 		}
@@ -1633,7 +1627,7 @@ static int NCR5380_transfer_pio(struct S
 		                          STATUS_REG, SR_REQ, 0, 5 * HZ) < 0)
 			break;
 
-		dprintk(NDEBUG_HANDSHAKE, "scsi%d: req false, handshake complete\n", HOSTNO);
+		dsprintk(NDEBUG_HANDSHAKE, instance, "REQ negated, handshake complete\n");
 
 		/*
 		 * We have several special cases to consider during REQ/ACK handshaking :
@@ -1654,7 +1648,7 @@ static int NCR5380_transfer_pio(struct S
 		}
 	} while (--c);
 
-	dprintk(NDEBUG_PIO, "scsi%d: residual %d\n", HOSTNO, c);
+	dsprintk(NDEBUG_PIO, instance, "residual %d\n", c);
 
 	*count = c;
 	*data = d;
@@ -1800,9 +1794,8 @@ static int NCR5380_transfer_dma(struct S
 	}
 	hostdata->dma_len = c;
 
-	dprintk(NDEBUG_DMA, "scsi%d: initializing DMA for %s, %d bytes %s %p\n",
-		instance->host_no, (p & SR_IO) ? "reading" : "writing",
-		c, (p & SR_IO) ? "to" : "from", *data);
+	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 */
 
@@ -1838,9 +1831,8 @@ static int NCR5380_transfer_dma(struct S
 	if (hostdata->read_overruns && (p & SR_IO))
 		c -= hostdata->read_overruns;
 
-	dprintk(NDEBUG_DMA, "scsi%d: initializing DMA for %s, %d bytes %s %p\n",
-		   HOSTNO, (p & SR_IO) ? "reading" : "writing",
-		   c, (p & SR_IO) ? "to" : "from", d);
+	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 |
@@ -1987,9 +1979,9 @@ static void NCR5380_information_transfer
 					 * they are at contiguous physical addresses.
 					 */
 					merge_contiguous_buffers(cmd);
-					dprintk(NDEBUG_INFORMATION, "scsi%d: %d bytes and %d buffers left\n",
-						   HOSTNO, cmd->SCp.this_residual,
-						   cmd->SCp.buffers_residual);
+					dsprintk(NDEBUG_INFORMATION, instance, "%d bytes and %d buffers left\n",
+					         cmd->SCp.this_residual,
+					         cmd->SCp.buffers_residual);
 				}
 
 				/*
@@ -2077,11 +2069,12 @@ static void NCR5380_information_transfer
 #ifdef SUPPORT_TAGS
 					cmd_free_tag(cmd);
 					if (status_byte(cmd->SCp.Status) == QUEUE_FULL) {
-						struct tag_alloc *ta = &hostdata->TagAlloc[scmd_id(cmd)][cmd->device->lun];
-						dprintk(NDEBUG_TAGS, "scsi%d: target %d lun %llu returned "
-							   "QUEUE_FULL after %d commands\n",
-							   HOSTNO, cmd->device->id, cmd->device->lun,
-							   ta->nr_allocated);
+						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;
 					}
@@ -2135,10 +2128,8 @@ static void NCR5380_information_transfer
 						cmd->device->tagged_supported = 0;
 						hostdata->busy[cmd->device->id] |= (1 << cmd->device->lun);
 						cmd->tag = TAG_NONE;
-						dprintk(NDEBUG_TAGS, "scsi%d: target %d lun %llu rejected "
-							   "QUEUE_TAG message; tagged queuing "
-							   "disabled\n",
-							   HOSTNO, cmd->device->id, cmd->device->lun);
+						dsprintk(NDEBUG_TAGS, instance, "target %d lun %llu rejected QUEUE_TAG message; tagged queuing disabled\n",
+						         scmd_id(cmd), cmd->device->lun);
 						break;
 					}
 					break;
@@ -2197,14 +2188,15 @@ static void NCR5380_information_transfer
 
 					spin_unlock_irq(&hostdata->lock);
 
-					dprintk(NDEBUG_EXTENDED, "scsi%d: receiving extended message\n", HOSTNO);
+					dsprintk(NDEBUG_EXTENDED, instance, "receiving extended message\n");
 
 					len = 2;
 					data = extended_msg + 1;
 					phase = PHASE_MSGIN;
 					NCR5380_transfer_pio(instance, &phase, &len, &data);
-					dprintk(NDEBUG_EXTENDED, "scsi%d: length=%d, code=0x%02x\n", HOSTNO,
-						   (int)extended_msg[1], (int)extended_msg[2]);
+					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) {
@@ -2215,8 +2207,8 @@ static void NCR5380_information_transfer
 						phase = PHASE_MSGIN;
 
 						NCR5380_transfer_pio(instance, &phase, &len, &data);
-						dprintk(NDEBUG_EXTENDED, "scsi%d: message received, residual %d\n",
-							   HOSTNO, len);
+						dsprintk(NDEBUG_EXTENDED, instance, "message received, residual %d\n",
+						         len);
 
 						switch (extended_msg[2]) {
 						case EXTENDED_SDTR:
@@ -2344,7 +2336,7 @@ static void NCR5380_reselect(struct Scsi
 
 	target_mask = NCR5380_read(CURRENT_SCSI_DATA_REG) & ~(hostdata->id_mask);
 
-	dprintk(NDEBUG_RESELECTION, "scsi%d: reselect\n", HOSTNO);
+	dsprintk(NDEBUG_RESELECTION, instance, "reselect\n");
 
 	/*
 	 * At this point, we have detected that our SCSI ID is on the bus,
@@ -2414,8 +2406,8 @@ static void NCR5380_reselect(struct Scsi
 		if (!NCR5380_transfer_pio(instance, &phase, &len, &data) &&
 		    msg[1] == SIMPLE_QUEUE_TAG)
 			tag = msg[2];
-		dprintk(NDEBUG_TAGS, "scsi%d: target mask %02x, lun %d sent tag %d at "
-			   "reselection\n", HOSTNO, target_mask, lun, tag);
+		dsprintk(NDEBUG_TAGS, instance, "reselect: target mask %02x, lun %d sent tag %d\n",
+		         target_mask, lun, tag);
 	}
 #endif
 
@@ -2500,14 +2492,14 @@ static void NCR5380_reselect(struct Scsi
 		if (!NCR5380_transfer_pio(instance, &phase, &len, &data) &&
 		    msg[1] == SIMPLE_QUEUE_TAG)
 			tag = msg[2];
-		dprintk(NDEBUG_TAGS, "scsi%d: target mask %02x, lun %d sent tag %d at reselection\n"
-			HOSTNO, target_mask, lun, tag);
+		dsprintk(NDEBUG_TAGS, instance, "reselect: target mask %02x, lun %d sent tag %d\n"
+		         target_mask, lun, tag);
 	}
 #endif
 
 	hostdata->connected = tmp;
-	dprintk(NDEBUG_RESELECTION, "scsi%d: nexus established, target = %d, lun = %llu, tag = %d\n",
-		   HOSTNO, tmp->device->id, tmp->device->lun, tmp->tag);
+	dsprintk(NDEBUG_RESELECTION, instance, "nexus established, target %d, lun %llu, tag %d\n",
+	         scmd_id(tmp), tmp->device->lun, tmp->tag);
 }
 
 
Index: linux/drivers/scsi/NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/NCR5380.c	2015-11-18 19:34:32.000000000 +1100
+++ linux/drivers/scsi/NCR5380.c	2015-11-18 19:34:33.000000000 +1100
@@ -922,9 +922,8 @@ static void NCR5380_main(struct work_str
 		    && !hostdata->dmalen
 #endif
 		    ) {
-			dprintk(NDEBUG_MAIN, "scsi%d : main() : performing information transfer\n", instance->host_no);
+			dsprintk(NDEBUG_MAIN, instance, "main: performing information transfer\n");
 			NCR5380_information_transfer(instance);
-			dprintk(NDEBUG_MAIN, "scsi%d : main() : done set false\n", instance->host_no);
 			done = 0;
 		}
 	} while (!done);
@@ -982,8 +981,8 @@ static irqreturn_t NCR5380_intr(int irq,
 		unsigned char mr = NCR5380_read(MODE_REG);
 		unsigned char sr = NCR5380_read(STATUS_REG);
 
-		dprintk(NDEBUG_INTR, "scsi%d: IRQ %d, BASR 0x%02x, SR 0x%02x, MR 0x%02x\n",
-		        instance->host_no, irq, basr, sr, mr);
+		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)) {
@@ -992,7 +991,7 @@ static irqreturn_t NCR5380_intr(int irq,
 			 * for End of DMA errata need to happen in DMA Mode.
 			 */
 
-			dprintk(NDEBUG_INTR, "scsi%d: interrupt in DMA mode\n", intance->host_no);
+			dsprintk(NDEBUG_INTR, instance, "interrupt in DMA mode\n");
 
 			int transferred;
 
@@ -1019,8 +1018,7 @@ static irqreturn_t NCR5380_intr(int irq,
 			NCR5380_write(SELECT_ENABLE_REG, 0);
 			NCR5380_read(RESET_PARITY_INTERRUPT_REG);
 
-			dprintk(NDEBUG_INTR, "scsi%d: interrupt with SEL and IO\n",
-			        instance->host_no);
+			dsprintk(NDEBUG_INTR, instance, "interrupt with SEL and IO\n");
 
 			if (!hostdata->connected) {
 				NCR5380_reselect(instance);
@@ -1032,7 +1030,7 @@ static irqreturn_t NCR5380_intr(int irq,
 			/* Probably Bus Reset */
 			NCR5380_read(RESET_PARITY_INTERRUPT_REG);
 
-			dprintk(NDEBUG_INTR, "scsi%d: unknown interrupt\n", instance->host_no);
+			dsprintk(NDEBUG_INTR, instance, "unknown interrupt\n");
 		}
 		handled = 1;
 	} else {
@@ -1087,7 +1085,8 @@ static struct scsi_cmnd *NCR5380_select(
 	int err;
 
 	NCR5380_dprint(NDEBUG_ARBITRATION, instance);
-	dprintk(NDEBUG_ARBITRATION, "scsi%d : starting arbitration, id = %d\n", instance->host_no, instance->this_id);
+	dsprintk(NDEBUG_ARBITRATION, instance, "starting arbitration, id = %d\n",
+	         instance->this_id);
 
 	/*
 	 * Arbitration and selection phases are slow and involve dropping the
@@ -1139,7 +1138,7 @@ static struct scsi_cmnd *NCR5380_select(
 	/* 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);
-		dprintk(NDEBUG_ARBITRATION, "scsi%d : lost arbitration, deasserting MR_ARBITRATE\n", instance->host_no);
+		dsprintk(NDEBUG_ARBITRATION, instance, "lost arbitration, deasserting MR_ARBITRATE\n");
 		spin_lock_irq(&hostdata->lock);
 		goto out;
 	}
@@ -1184,7 +1183,7 @@ static struct scsi_cmnd *NCR5380_select(
 		goto out;
 	}
 
-	dprintk(NDEBUG_ARBITRATION, "scsi%d : won arbitration\n", instance->host_no);
+	dsprintk(NDEBUG_ARBITRATION, instance, "won arbitration\n");
 
 	/* 
 	 * Now that we have won arbitration, start Selection process, asserting 
@@ -1238,7 +1237,7 @@ static struct scsi_cmnd *NCR5380_select(
 
 	udelay(1);
 
-	dprintk(NDEBUG_SELECTION, "scsi%d : selecting target %d\n", instance->host_no, scmd_id(cmd));
+	dsprintk(NDEBUG_SELECTION, instance, "selecting target %d\n", scmd_id(cmd));
 
 	/* 
 	 * The SCSI specification calls for a 250 ms timeout for the actual 
@@ -1312,7 +1311,8 @@ static struct scsi_cmnd *NCR5380_select(
 		goto out;
 	}
 
-	dprintk(NDEBUG_SELECTION, "scsi%d : target %d selected, going into MESSAGE OUT phase.\n", instance->host_no, cmd->device->id);
+	dsprintk(NDEBUG_SELECTION, instance, "target %d selected, going into MESSAGE OUT phase.\n",
+	         scmd_id(cmd));
 	tmp[0] = IDENTIFY(((instance->irq == NO_IRQ) ? 0 : 1), cmd->device->lun);
 
 	len = 1;
@@ -1322,7 +1322,7 @@ static struct scsi_cmnd *NCR5380_select(
 	data = tmp;
 	phase = PHASE_MSGOUT;
 	NCR5380_transfer_pio(instance, &phase, &len, &data);
-	dprintk(NDEBUG_SELECTION, "scsi%d : nexus established.\n", instance->host_no);
+	dsprintk(NDEBUG_SELECTION, instance, "nexus established.\n");
 	/* XXX need to handle errors here */
 
 	hostdata->connected = cmd;
@@ -1369,11 +1369,6 @@ static int NCR5380_transfer_pio(struct S
 	int c = *count;
 	unsigned char *d = *data;
 
-	if (!(p & SR_IO))
-		dprintk(NDEBUG_PIO, "scsi%d : pio write %d bytes\n", instance->host_no, c);
-	else
-		dprintk(NDEBUG_PIO, "scsi%d : pio read %d bytes\n", instance->host_no, c);
-
 	/* 
 	 * The NCR5380 chip will only drive the SCSI bus when the 
 	 * phase specified in the appropriate bits of the TARGET COMMAND
@@ -1391,12 +1386,12 @@ static int NCR5380_transfer_pio(struct S
 		if (NCR5380_poll_politely(instance, STATUS_REG, SR_REQ, SR_REQ, HZ) < 0)
 			break;
 
-		dprintk(NDEBUG_HANDSHAKE, "scsi%d : REQ detected\n", instance->host_no);
+		dsprintk(NDEBUG_HANDSHAKE, instance, "REQ asserted\n");
 
 		/* Check for phase mismatch */
 		if ((NCR5380_read(STATUS_REG) & PHASE_MASK) != p) {
-			dprintk(NDEBUG_HANDSHAKE, "scsi%d : phase mismatch\n", instance->host_no);
-			NCR5380_dprint_phase(NDEBUG_HANDSHAKE, instance);
+			dsprintk(NDEBUG_PIO, instance, "phase mismatch\n");
+			NCR5380_dprint_phase(NDEBUG_PIO, instance);
 			break;
 		}
 		/* Do actual transfer from SCSI bus to / from memory */
@@ -1433,7 +1428,7 @@ static int NCR5380_transfer_pio(struct S
 		                          STATUS_REG, SR_REQ, 0, 5 * HZ) < 0)
 			break;
 
-		dprintk(NDEBUG_HANDSHAKE, "scsi%d : req false, handshake complete\n", instance->host_no);
+		dsprintk(NDEBUG_HANDSHAKE, instance, "REQ negated, handshake complete\n");
 
 /*
  * We have several special cases to consider during REQ/ACK handshaking : 
@@ -1454,7 +1449,7 @@ static int NCR5380_transfer_pio(struct S
 		}
 	} while (--c);
 
-	dprintk(NDEBUG_PIO, "scsi%d : residual %d\n", instance->host_no, c);
+	dsprintk(NDEBUG_PIO, instance, "residual %d\n", c);
 
 	*count = c;
 	*data = d;
@@ -1604,8 +1599,10 @@ static int NCR5380_transfer_dma(struct S
 		if (!(hostdata->flags & FLAG_NO_DMA_FIXUPS))
 			c -= 2;
 	}
-	dprintk(NDEBUG_DMA, "scsi%d : initializing DMA channel %d for %s, %d bytes %s %0x\n", instance->host_no, instance->dma_channel, (p & SR_IO) ? "reading" : "writing", c, (p & SR_IO) ? "to" : "from", (unsigned) d);
 	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));
@@ -1707,7 +1704,8 @@ static int NCR5380_transfer_dma(struct S
 		}
 	}
 
-	dprintk(NDEBUG_DMA, "scsi%d : polled DMA transfer complete, basr 0x%X, sr 0x%X\n", instance->host_no, tmp, NCR5380_read(STATUS_REG));
+	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);
@@ -1877,7 +1875,9 @@ static void NCR5380_information_transfer
 					--cmd->SCp.buffers_residual;
 					cmd->SCp.this_residual = cmd->SCp.buffer->length;
 					cmd->SCp.ptr = sg_virt(cmd->SCp.buffer);
-					dprintk(NDEBUG_INFORMATION, "scsi%d : %d bytes and %d buffers left\n", instance->host_no, cmd->SCp.this_residual, cmd->SCp.buffers_residual);
+					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 
@@ -2032,14 +2032,15 @@ static void NCR5380_information_transfer
 
 					spin_unlock_irq(&hostdata->lock);
 
-					dprintk(NDEBUG_EXTENDED, "scsi%d : receiving extended message\n", instance->host_no);
+					dsprintk(NDEBUG_EXTENDED, instance, "receiving extended message\n");
 
 					len = 2;
 					data = extended_msg + 1;
 					phase = PHASE_MSGIN;
 					NCR5380_transfer_pio(instance, &phase, &len, &data);
-
-					dprintk(NDEBUG_EXTENDED, "scsi%d : length=%d, code=0x%02x\n", instance->host_no, (int) extended_msg[1], (int) extended_msg[2]);
+					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) {
@@ -2050,7 +2051,8 @@ static void NCR5380_information_transfer
 						phase = PHASE_MSGIN;
 
 						NCR5380_transfer_pio(instance, &phase, &len, &data);
-						dprintk(NDEBUG_EXTENDED, "scsi%d : message received, residual %d\n", instance->host_no, len);
+						dsprintk(NDEBUG_EXTENDED, instance, "message received, residual %d\n",
+						         len);
 
 						switch (extended_msg[2]) {
 						case EXTENDED_SDTR:
@@ -2167,7 +2169,8 @@ static void NCR5380_reselect(struct Scsi
 	NCR5380_write(MODE_REG, MR_BASE);
 
 	target_mask = NCR5380_read(CURRENT_SCSI_DATA_REG) & ~(hostdata->id_mask);
-	dprintk(NDEBUG_RESELECTION, "scsi%d : reselect\n", instance->host_no);
+
+	dsprintk(NDEBUG_RESELECTION, instance, "reselect\n");
 
 	/* 
 	 * At this point, we have detected that our SCSI ID is on the bus,
@@ -2256,8 +2259,8 @@ static void NCR5380_reselect(struct Scsi
 	NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
 
 	hostdata->connected = tmp;
-	dprintk(NDEBUG_RESELECTION, "scsi%d : nexus established, target = %d, lun = %llu, tag = %d\n",
-	        instance->host_no, tmp->device->id, tmp->device->lun, tmp->tag);
+	dsprintk(NDEBUG_RESELECTION, instance, "nexus established, target %d, lun %llu, tag %d\n",
+	         scmd_id(tmp), tmp->device->lun, tmp->tag);
 }
 
 /*



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

* [PATCH 64/71] atari_NCR5380: Eliminate HOSTNO macro
@ 2015-11-18  8:35   ` Finn Thain
  0 siblings, 0 replies; 268+ messages in thread
From: Finn Thain @ 2015-11-18  8:35 UTC (permalink / raw)
  To: James E.J. Bottomley, Michael Schmitz, linux-m68k, linux-scsi,
	linux-kernel

[-- Attachment #1: atari_NCR5380-remove-HOSTNO-dprintk --]
[-- Type: text/plain, Size: 22251 bytes --]

Keep the two core driver forks in sync.

Signed-off-by: Finn Thain <fthain@telegraphics.com.au>

---
 drivers/scsi/NCR5380.c       |   71 +++++++++++++++--------------
 drivers/scsi/atari_NCR5380.c |  102 +++++++++++++++++++------------------------
 2 files changed, 84 insertions(+), 89 deletions(-)

Index: linux/drivers/scsi/atari_NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/atari_NCR5380.c	2015-11-18 19:34:32.000000000 +1100
+++ linux/drivers/scsi/atari_NCR5380.c	2015-11-18 19:34:33.000000000 +1100
@@ -175,8 +175,6 @@
  * possible) function may be used.
  */
 
-#define	HOSTNO		instance->host_no
-
 static int do_abort(struct Scsi_Host *);
 static void do_reset(struct Scsi_Host *);
 
@@ -1021,10 +1019,8 @@ static void NCR5380_main(struct work_str
 		    && !hostdata->dma_len
 #endif
 		    ) {
-			dprintk(NDEBUG_MAIN, "scsi%d: main: performing information transfer\n",
-				    HOSTNO);
+			dsprintk(NDEBUG_MAIN, instance, "main: performing information transfer\n");
 			NCR5380_information_transfer(instance);
-			dprintk(NDEBUG_MAIN, "scsi%d: main: done set false\n", HOSTNO);
 			done = 0;
 		}
 	} while (!done);
@@ -1061,7 +1057,7 @@ static void NCR5380_dma_complete(struct
 			    (BASR_PHASE_MATCH|BASR_ACK)) {
 				saved_data = NCR5380_read(INPUT_DATA_REG);
 				overrun = 1;
-				dprintk(NDEBUG_DMA, "scsi%d: read overrun handled\n", HOSTNO);
+				dsprintk(NDEBUG_DMA, instance, "read overrun handled\n");
 			}
 		}
 	}
@@ -1166,8 +1162,8 @@ static irqreturn_t NCR5380_intr(int irq,
 		unsigned char mr = NCR5380_read(MODE_REG);
 		unsigned char sr = NCR5380_read(STATUS_REG);
 
-		dprintk(NDEBUG_INTR, "scsi%d: IRQ %d, BASR 0x%02x, SR 0x%02x, MR 0x%02x\n",
-		        HOSTNO, irq, basr, sr, mr);
+		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)) {
@@ -1176,7 +1172,7 @@ static irqreturn_t NCR5380_intr(int irq,
 			 * for End of DMA errata need to happen in DMA Mode.
 			 */
 
-			dprintk(NDEBUG_INTR, "scsi%d: interrupt in DMA mode\n", HOSTNO);
+			dsprintk(NDEBUG_INTR, instance, "interrupt in DMA mode\n");
 
 			if (hostdata->connected) {
 				NCR5380_dma_complete(instance);
@@ -1193,8 +1189,7 @@ static irqreturn_t NCR5380_intr(int irq,
 			NCR5380_write(SELECT_ENABLE_REG, 0);
 			NCR5380_read(RESET_PARITY_INTERRUPT_REG);
 
-			dprintk(NDEBUG_INTR, "scsi%d: interrupt with SEL and IO\n",
-			        HOSTNO);
+			dsprintk(NDEBUG_INTR, instance, "interrupt with SEL and IO\n");
 
 			if (!hostdata->connected) {
 				NCR5380_reselect(instance);
@@ -1206,7 +1201,7 @@ static irqreturn_t NCR5380_intr(int irq,
 			/* Probably Bus Reset */
 			NCR5380_read(RESET_PARITY_INTERRUPT_REG);
 
-			dprintk(NDEBUG_INTR, "scsi%d: unknown interrupt\n", HOSTNO);
+			dsprintk(NDEBUG_INTR, instance, "unknown interrupt\n");
 #ifdef SUN3_SCSI_VME
 			dregs->csr |= CSR_DMA_ENABLE;
 #endif
@@ -1263,8 +1258,8 @@ static struct scsi_cmnd *NCR5380_select(
 	int err;
 
 	NCR5380_dprint(NDEBUG_ARBITRATION, instance);
-	dprintk(NDEBUG_ARBITRATION, "scsi%d: starting arbitration, id = %d\n", HOSTNO,
-		   instance->this_id);
+	dsprintk(NDEBUG_ARBITRATION, instance, "starting arbitration, id = %d\n",
+	         instance->this_id);
 
 	/*
 	 * Arbitration and selection phases are slow and involve dropping the
@@ -1318,8 +1313,7 @@ static struct scsi_cmnd *NCR5380_select(
 	    (NCR5380_read(CURRENT_SCSI_DATA_REG) & hostdata->id_higher_mask) ||
 	    (NCR5380_read(INITIATOR_COMMAND_REG) & ICR_ARBITRATION_LOST)) {
 		NCR5380_write(MODE_REG, MR_BASE);
-		dprintk(NDEBUG_ARBITRATION, "scsi%d: lost arbitration, deasserting MR_ARBITRATE\n",
-			   HOSTNO);
+		dsprintk(NDEBUG_ARBITRATION, instance, "lost arbitration, deasserting MR_ARBITRATE\n");
 		spin_lock_irq(&hostdata->lock);
 		goto out;
 	}
@@ -1365,7 +1359,7 @@ static struct scsi_cmnd *NCR5380_select(
 		goto out;
 	}
 
-	dprintk(NDEBUG_ARBITRATION, "scsi%d: won arbitration\n", HOSTNO);
+	dsprintk(NDEBUG_ARBITRATION, instance, "won arbitration\n");
 
 	/*
 	 * Now that we have won arbitration, start Selection process, asserting
@@ -1421,7 +1415,7 @@ static struct scsi_cmnd *NCR5380_select(
 
 	udelay(1);
 
-	dprintk(NDEBUG_SELECTION, "scsi%d: selecting target %d\n", HOSTNO, cmd->device->id);
+	dsprintk(NDEBUG_SELECTION, instance, "selecting target %d\n", scmd_id(cmd));
 
 	/*
 	 * The SCSI specification calls for a 250 ms timeout for the actual
@@ -1495,8 +1489,8 @@ static struct scsi_cmnd *NCR5380_select(
 		goto out;
 	}
 
-	dprintk(NDEBUG_SELECTION, "scsi%d: target %d selected, going into MESSAGE OUT phase.\n",
-		   HOSTNO, cmd->device->id);
+	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
@@ -1515,7 +1509,7 @@ static struct scsi_cmnd *NCR5380_select(
 	data = tmp;
 	phase = PHASE_MSGOUT;
 	NCR5380_transfer_pio(instance, &phase, &len, &data);
-	dprintk(NDEBUG_SELECTION, "scsi%d: nexus established.\n", HOSTNO);
+	dsprintk(NDEBUG_SELECTION, instance, "nexus established.\n");
 	/* XXX need to handle errors here */
 
 	hostdata->connected = cmd;
@@ -1587,11 +1581,11 @@ static int NCR5380_transfer_pio(struct S
 		if (NCR5380_poll_politely(instance, STATUS_REG, SR_REQ, SR_REQ, HZ) < 0)
 			break;
 
-		dprintk(NDEBUG_HANDSHAKE, "scsi%d: REQ detected\n", HOSTNO);
+		dsprintk(NDEBUG_HANDSHAKE, instance, "REQ asserted\n");
 
 		/* Check for phase mismatch */
 		if ((NCR5380_read(STATUS_REG) & PHASE_MASK) != p) {
-			dprintk(NDEBUG_PIO, "scsi%d: phase mismatch\n", HOSTNO);
+			dsprintk(NDEBUG_PIO, instance, "phase mismatch\n");
 			NCR5380_dprint_phase(NDEBUG_PIO, instance);
 			break;
 		}
@@ -1633,7 +1627,7 @@ static int NCR5380_transfer_pio(struct S
 		                          STATUS_REG, SR_REQ, 0, 5 * HZ) < 0)
 			break;
 
-		dprintk(NDEBUG_HANDSHAKE, "scsi%d: req false, handshake complete\n", HOSTNO);
+		dsprintk(NDEBUG_HANDSHAKE, instance, "REQ negated, handshake complete\n");
 
 		/*
 		 * We have several special cases to consider during REQ/ACK handshaking :
@@ -1654,7 +1648,7 @@ static int NCR5380_transfer_pio(struct S
 		}
 	} while (--c);
 
-	dprintk(NDEBUG_PIO, "scsi%d: residual %d\n", HOSTNO, c);
+	dsprintk(NDEBUG_PIO, instance, "residual %d\n", c);
 
 	*count = c;
 	*data = d;
@@ -1800,9 +1794,8 @@ static int NCR5380_transfer_dma(struct S
 	}
 	hostdata->dma_len = c;
 
-	dprintk(NDEBUG_DMA, "scsi%d: initializing DMA for %s, %d bytes %s %p\n",
-		instance->host_no, (p & SR_IO) ? "reading" : "writing",
-		c, (p & SR_IO) ? "to" : "from", *data);
+	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 */
 
@@ -1838,9 +1831,8 @@ static int NCR5380_transfer_dma(struct S
 	if (hostdata->read_overruns && (p & SR_IO))
 		c -= hostdata->read_overruns;
 
-	dprintk(NDEBUG_DMA, "scsi%d: initializing DMA for %s, %d bytes %s %p\n",
-		   HOSTNO, (p & SR_IO) ? "reading" : "writing",
-		   c, (p & SR_IO) ? "to" : "from", d);
+	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 |
@@ -1987,9 +1979,9 @@ static void NCR5380_information_transfer
 					 * they are at contiguous physical addresses.
 					 */
 					merge_contiguous_buffers(cmd);
-					dprintk(NDEBUG_INFORMATION, "scsi%d: %d bytes and %d buffers left\n",
-						   HOSTNO, cmd->SCp.this_residual,
-						   cmd->SCp.buffers_residual);
+					dsprintk(NDEBUG_INFORMATION, instance, "%d bytes and %d buffers left\n",
+					         cmd->SCp.this_residual,
+					         cmd->SCp.buffers_residual);
 				}
 
 				/*
@@ -2077,11 +2069,12 @@ static void NCR5380_information_transfer
 #ifdef SUPPORT_TAGS
 					cmd_free_tag(cmd);
 					if (status_byte(cmd->SCp.Status) == QUEUE_FULL) {
-						struct tag_alloc *ta = &hostdata->TagAlloc[scmd_id(cmd)][cmd->device->lun];
-						dprintk(NDEBUG_TAGS, "scsi%d: target %d lun %llu returned "
-							   "QUEUE_FULL after %d commands\n",
-							   HOSTNO, cmd->device->id, cmd->device->lun,
-							   ta->nr_allocated);
+						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;
 					}
@@ -2135,10 +2128,8 @@ static void NCR5380_information_transfer
 						cmd->device->tagged_supported = 0;
 						hostdata->busy[cmd->device->id] |= (1 << cmd->device->lun);
 						cmd->tag = TAG_NONE;
-						dprintk(NDEBUG_TAGS, "scsi%d: target %d lun %llu rejected "
-							   "QUEUE_TAG message; tagged queuing "
-							   "disabled\n",
-							   HOSTNO, cmd->device->id, cmd->device->lun);
+						dsprintk(NDEBUG_TAGS, instance, "target %d lun %llu rejected QUEUE_TAG message; tagged queuing disabled\n",
+						         scmd_id(cmd), cmd->device->lun);
 						break;
 					}
 					break;
@@ -2197,14 +2188,15 @@ static void NCR5380_information_transfer
 
 					spin_unlock_irq(&hostdata->lock);
 
-					dprintk(NDEBUG_EXTENDED, "scsi%d: receiving extended message\n", HOSTNO);
+					dsprintk(NDEBUG_EXTENDED, instance, "receiving extended message\n");
 
 					len = 2;
 					data = extended_msg + 1;
 					phase = PHASE_MSGIN;
 					NCR5380_transfer_pio(instance, &phase, &len, &data);
-					dprintk(NDEBUG_EXTENDED, "scsi%d: length=%d, code=0x%02x\n", HOSTNO,
-						   (int)extended_msg[1], (int)extended_msg[2]);
+					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) {
@@ -2215,8 +2207,8 @@ static void NCR5380_information_transfer
 						phase = PHASE_MSGIN;
 
 						NCR5380_transfer_pio(instance, &phase, &len, &data);
-						dprintk(NDEBUG_EXTENDED, "scsi%d: message received, residual %d\n",
-							   HOSTNO, len);
+						dsprintk(NDEBUG_EXTENDED, instance, "message received, residual %d\n",
+						         len);
 
 						switch (extended_msg[2]) {
 						case EXTENDED_SDTR:
@@ -2344,7 +2336,7 @@ static void NCR5380_reselect(struct Scsi
 
 	target_mask = NCR5380_read(CURRENT_SCSI_DATA_REG) & ~(hostdata->id_mask);
 
-	dprintk(NDEBUG_RESELECTION, "scsi%d: reselect\n", HOSTNO);
+	dsprintk(NDEBUG_RESELECTION, instance, "reselect\n");
 
 	/*
 	 * At this point, we have detected that our SCSI ID is on the bus,
@@ -2414,8 +2406,8 @@ static void NCR5380_reselect(struct Scsi
 		if (!NCR5380_transfer_pio(instance, &phase, &len, &data) &&
 		    msg[1] == SIMPLE_QUEUE_TAG)
 			tag = msg[2];
-		dprintk(NDEBUG_TAGS, "scsi%d: target mask %02x, lun %d sent tag %d at "
-			   "reselection\n", HOSTNO, target_mask, lun, tag);
+		dsprintk(NDEBUG_TAGS, instance, "reselect: target mask %02x, lun %d sent tag %d\n",
+		         target_mask, lun, tag);
 	}
 #endif
 
@@ -2500,14 +2492,14 @@ static void NCR5380_reselect(struct Scsi
 		if (!NCR5380_transfer_pio(instance, &phase, &len, &data) &&
 		    msg[1] == SIMPLE_QUEUE_TAG)
 			tag = msg[2];
-		dprintk(NDEBUG_TAGS, "scsi%d: target mask %02x, lun %d sent tag %d at reselection\n"
-			HOSTNO, target_mask, lun, tag);
+		dsprintk(NDEBUG_TAGS, instance, "reselect: target mask %02x, lun %d sent tag %d\n"
+		         target_mask, lun, tag);
 	}
 #endif
 
 	hostdata->connected = tmp;
-	dprintk(NDEBUG_RESELECTION, "scsi%d: nexus established, target = %d, lun = %llu, tag = %d\n",
-		   HOSTNO, tmp->device->id, tmp->device->lun, tmp->tag);
+	dsprintk(NDEBUG_RESELECTION, instance, "nexus established, target %d, lun %llu, tag %d\n",
+	         scmd_id(tmp), tmp->device->lun, tmp->tag);
 }
 
 
Index: linux/drivers/scsi/NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/NCR5380.c	2015-11-18 19:34:32.000000000 +1100
+++ linux/drivers/scsi/NCR5380.c	2015-11-18 19:34:33.000000000 +1100
@@ -922,9 +922,8 @@ static void NCR5380_main(struct work_str
 		    && !hostdata->dmalen
 #endif
 		    ) {
-			dprintk(NDEBUG_MAIN, "scsi%d : main() : performing information transfer\n", instance->host_no);
+			dsprintk(NDEBUG_MAIN, instance, "main: performing information transfer\n");
 			NCR5380_information_transfer(instance);
-			dprintk(NDEBUG_MAIN, "scsi%d : main() : done set false\n", instance->host_no);
 			done = 0;
 		}
 	} while (!done);
@@ -982,8 +981,8 @@ static irqreturn_t NCR5380_intr(int irq,
 		unsigned char mr = NCR5380_read(MODE_REG);
 		unsigned char sr = NCR5380_read(STATUS_REG);
 
-		dprintk(NDEBUG_INTR, "scsi%d: IRQ %d, BASR 0x%02x, SR 0x%02x, MR 0x%02x\n",
-		        instance->host_no, irq, basr, sr, mr);
+		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)) {
@@ -992,7 +991,7 @@ static irqreturn_t NCR5380_intr(int irq,
 			 * for End of DMA errata need to happen in DMA Mode.
 			 */
 
-			dprintk(NDEBUG_INTR, "scsi%d: interrupt in DMA mode\n", intance->host_no);
+			dsprintk(NDEBUG_INTR, instance, "interrupt in DMA mode\n");
 
 			int transferred;
 
@@ -1019,8 +1018,7 @@ static irqreturn_t NCR5380_intr(int irq,
 			NCR5380_write(SELECT_ENABLE_REG, 0);
 			NCR5380_read(RESET_PARITY_INTERRUPT_REG);
 
-			dprintk(NDEBUG_INTR, "scsi%d: interrupt with SEL and IO\n",
-			        instance->host_no);
+			dsprintk(NDEBUG_INTR, instance, "interrupt with SEL and IO\n");
 
 			if (!hostdata->connected) {
 				NCR5380_reselect(instance);
@@ -1032,7 +1030,7 @@ static irqreturn_t NCR5380_intr(int irq,
 			/* Probably Bus Reset */
 			NCR5380_read(RESET_PARITY_INTERRUPT_REG);
 
-			dprintk(NDEBUG_INTR, "scsi%d: unknown interrupt\n", instance->host_no);
+			dsprintk(NDEBUG_INTR, instance, "unknown interrupt\n");
 		}
 		handled = 1;
 	} else {
@@ -1087,7 +1085,8 @@ static struct scsi_cmnd *NCR5380_select(
 	int err;
 
 	NCR5380_dprint(NDEBUG_ARBITRATION, instance);
-	dprintk(NDEBUG_ARBITRATION, "scsi%d : starting arbitration, id = %d\n", instance->host_no, instance->this_id);
+	dsprintk(NDEBUG_ARBITRATION, instance, "starting arbitration, id = %d\n",
+	         instance->this_id);
 
 	/*
 	 * Arbitration and selection phases are slow and involve dropping the
@@ -1139,7 +1138,7 @@ static struct scsi_cmnd *NCR5380_select(
 	/* 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);
-		dprintk(NDEBUG_ARBITRATION, "scsi%d : lost arbitration, deasserting MR_ARBITRATE\n", instance->host_no);
+		dsprintk(NDEBUG_ARBITRATION, instance, "lost arbitration, deasserting MR_ARBITRATE\n");
 		spin_lock_irq(&hostdata->lock);
 		goto out;
 	}
@@ -1184,7 +1183,7 @@ static struct scsi_cmnd *NCR5380_select(
 		goto out;
 	}
 
-	dprintk(NDEBUG_ARBITRATION, "scsi%d : won arbitration\n", instance->host_no);
+	dsprintk(NDEBUG_ARBITRATION, instance, "won arbitration\n");
 
 	/* 
 	 * Now that we have won arbitration, start Selection process, asserting 
@@ -1238,7 +1237,7 @@ static struct scsi_cmnd *NCR5380_select(
 
 	udelay(1);
 
-	dprintk(NDEBUG_SELECTION, "scsi%d : selecting target %d\n", instance->host_no, scmd_id(cmd));
+	dsprintk(NDEBUG_SELECTION, instance, "selecting target %d\n", scmd_id(cmd));
 
 	/* 
 	 * The SCSI specification calls for a 250 ms timeout for the actual 
@@ -1312,7 +1311,8 @@ static struct scsi_cmnd *NCR5380_select(
 		goto out;
 	}
 
-	dprintk(NDEBUG_SELECTION, "scsi%d : target %d selected, going into MESSAGE OUT phase.\n", instance->host_no, cmd->device->id);
+	dsprintk(NDEBUG_SELECTION, instance, "target %d selected, going into MESSAGE OUT phase.\n",
+	         scmd_id(cmd));
 	tmp[0] = IDENTIFY(((instance->irq == NO_IRQ) ? 0 : 1), cmd->device->lun);
 
 	len = 1;
@@ -1322,7 +1322,7 @@ static struct scsi_cmnd *NCR5380_select(
 	data = tmp;
 	phase = PHASE_MSGOUT;
 	NCR5380_transfer_pio(instance, &phase, &len, &data);
-	dprintk(NDEBUG_SELECTION, "scsi%d : nexus established.\n", instance->host_no);
+	dsprintk(NDEBUG_SELECTION, instance, "nexus established.\n");
 	/* XXX need to handle errors here */
 
 	hostdata->connected = cmd;
@@ -1369,11 +1369,6 @@ static int NCR5380_transfer_pio(struct S
 	int c = *count;
 	unsigned char *d = *data;
 
-	if (!(p & SR_IO))
-		dprintk(NDEBUG_PIO, "scsi%d : pio write %d bytes\n", instance->host_no, c);
-	else
-		dprintk(NDEBUG_PIO, "scsi%d : pio read %d bytes\n", instance->host_no, c);
-
 	/* 
 	 * The NCR5380 chip will only drive the SCSI bus when the 
 	 * phase specified in the appropriate bits of the TARGET COMMAND
@@ -1391,12 +1386,12 @@ static int NCR5380_transfer_pio(struct S
 		if (NCR5380_poll_politely(instance, STATUS_REG, SR_REQ, SR_REQ, HZ) < 0)
 			break;
 
-		dprintk(NDEBUG_HANDSHAKE, "scsi%d : REQ detected\n", instance->host_no);
+		dsprintk(NDEBUG_HANDSHAKE, instance, "REQ asserted\n");
 
 		/* Check for phase mismatch */
 		if ((NCR5380_read(STATUS_REG) & PHASE_MASK) != p) {
-			dprintk(NDEBUG_HANDSHAKE, "scsi%d : phase mismatch\n", instance->host_no);
-			NCR5380_dprint_phase(NDEBUG_HANDSHAKE, instance);
+			dsprintk(NDEBUG_PIO, instance, "phase mismatch\n");
+			NCR5380_dprint_phase(NDEBUG_PIO, instance);
 			break;
 		}
 		/* Do actual transfer from SCSI bus to / from memory */
@@ -1433,7 +1428,7 @@ static int NCR5380_transfer_pio(struct S
 		                          STATUS_REG, SR_REQ, 0, 5 * HZ) < 0)
 			break;
 
-		dprintk(NDEBUG_HANDSHAKE, "scsi%d : req false, handshake complete\n", instance->host_no);
+		dsprintk(NDEBUG_HANDSHAKE, instance, "REQ negated, handshake complete\n");
 
 /*
  * We have several special cases to consider during REQ/ACK handshaking : 
@@ -1454,7 +1449,7 @@ static int NCR5380_transfer_pio(struct S
 		}
 	} while (--c);
 
-	dprintk(NDEBUG_PIO, "scsi%d : residual %d\n", instance->host_no, c);
+	dsprintk(NDEBUG_PIO, instance, "residual %d\n", c);
 
 	*count = c;
 	*data = d;
@@ -1604,8 +1599,10 @@ static int NCR5380_transfer_dma(struct S
 		if (!(hostdata->flags & FLAG_NO_DMA_FIXUPS))
 			c -= 2;
 	}
-	dprintk(NDEBUG_DMA, "scsi%d : initializing DMA channel %d for %s, %d bytes %s %0x\n", instance->host_no, instance->dma_channel, (p & SR_IO) ? "reading" : "writing", c, (p & SR_IO) ? "to" : "from", (unsigned) d);
 	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));
@@ -1707,7 +1704,8 @@ static int NCR5380_transfer_dma(struct S
 		}
 	}
 
-	dprintk(NDEBUG_DMA, "scsi%d : polled DMA transfer complete, basr 0x%X, sr 0x%X\n", instance->host_no, tmp, NCR5380_read(STATUS_REG));
+	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);
@@ -1877,7 +1875,9 @@ static void NCR5380_information_transfer
 					--cmd->SCp.buffers_residual;
 					cmd->SCp.this_residual = cmd->SCp.buffer->length;
 					cmd->SCp.ptr = sg_virt(cmd->SCp.buffer);
-					dprintk(NDEBUG_INFORMATION, "scsi%d : %d bytes and %d buffers left\n", instance->host_no, cmd->SCp.this_residual, cmd->SCp.buffers_residual);
+					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 
@@ -2032,14 +2032,15 @@ static void NCR5380_information_transfer
 
 					spin_unlock_irq(&hostdata->lock);
 
-					dprintk(NDEBUG_EXTENDED, "scsi%d : receiving extended message\n", instance->host_no);
+					dsprintk(NDEBUG_EXTENDED, instance, "receiving extended message\n");
 
 					len = 2;
 					data = extended_msg + 1;
 					phase = PHASE_MSGIN;
 					NCR5380_transfer_pio(instance, &phase, &len, &data);
-
-					dprintk(NDEBUG_EXTENDED, "scsi%d : length=%d, code=0x%02x\n", instance->host_no, (int) extended_msg[1], (int) extended_msg[2]);
+					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) {
@@ -2050,7 +2051,8 @@ static void NCR5380_information_transfer
 						phase = PHASE_MSGIN;
 
 						NCR5380_transfer_pio(instance, &phase, &len, &data);
-						dprintk(NDEBUG_EXTENDED, "scsi%d : message received, residual %d\n", instance->host_no, len);
+						dsprintk(NDEBUG_EXTENDED, instance, "message received, residual %d\n",
+						         len);
 
 						switch (extended_msg[2]) {
 						case EXTENDED_SDTR:
@@ -2167,7 +2169,8 @@ static void NCR5380_reselect(struct Scsi
 	NCR5380_write(MODE_REG, MR_BASE);
 
 	target_mask = NCR5380_read(CURRENT_SCSI_DATA_REG) & ~(hostdata->id_mask);
-	dprintk(NDEBUG_RESELECTION, "scsi%d : reselect\n", instance->host_no);
+
+	dsprintk(NDEBUG_RESELECTION, instance, "reselect\n");
 
 	/* 
 	 * At this point, we have detected that our SCSI ID is on the bus,
@@ -2256,8 +2259,8 @@ static void NCR5380_reselect(struct Scsi
 	NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
 
 	hostdata->connected = tmp;
-	dprintk(NDEBUG_RESELECTION, "scsi%d : nexus established, target = %d, lun = %llu, tag = %d\n",
-	        instance->host_no, tmp->device->id, tmp->device->lun, tmp->tag);
+	dsprintk(NDEBUG_RESELECTION, instance, "nexus established, target %d, lun %llu, tag %d\n",
+	         scmd_id(tmp), tmp->device->lun, tmp->tag);
 }
 
 /*

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

* [PATCH 65/71] atari_scsi, sun3_scsi: Remove global Scsi_Host pointer
  2015-11-18  8:34 ` Finn Thain
@ 2015-11-18  8:36   ` Finn Thain
  -1 siblings, 0 replies; 268+ messages in thread
From: Finn Thain @ 2015-11-18  8:36 UTC (permalink / raw)
  To: James E.J. Bottomley, Michael Schmitz, linux-m68k, linux-scsi,
	linux-kernel

[-- Attachment #1: atari_scsi-sun3_scsi-remove-global-instances --]
[-- Type: text/plain, Size: 9048 bytes --]

This refactoring removes two global Scsi_Host pointers. This
improves consistency with other ncr5380 drivers. Adopting the same
conventions as the other drivers makes them easier to read.

Signed-off-by: Finn Thain <fthain@telegraphics.com.au>

---
 drivers/scsi/atari_NCR5380.c |    5 +-
 drivers/scsi/atari_scsi.c    |   29 ++++++++---------
 drivers/scsi/sun3_scsi.c     |   72 ++++++++++---------------------------------
 3 files changed, 36 insertions(+), 70 deletions(-)

Index: linux/drivers/scsi/atari_scsi.c
===================================================================
--- linux.orig/drivers/scsi/atari_scsi.c	2015-11-18 19:34:20.000000000 +1100
+++ linux/drivers/scsi/atari_scsi.c	2015-11-18 19:34:34.000000000 +1100
@@ -159,14 +159,10 @@ static inline unsigned long SCSI_DMA_GET
 	return adr;
 }
 
-#define HOSTDATA_DMALEN		(((struct NCR5380_hostdata *) \
-				(atari_scsi_host->hostdata))->dma_len)
-
 #ifdef REAL_DMA
 static void atari_scsi_fetch_restbytes(void);
 #endif
 
-static struct Scsi_Host *atari_scsi_host;
 static unsigned char (*atari_scsi_reg_read)(unsigned char reg);
 static void (*atari_scsi_reg_write)(unsigned char reg, unsigned char value);
 
@@ -262,15 +258,17 @@ static void scsi_dma_buserr(int irq, voi
 #endif
 
 
-static irqreturn_t scsi_tt_intr(int irq, void *dummy)
+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;
 
 	dma_stat = tt_scsi_dma.dma_ctrl;
 
-	dprintk(NDEBUG_INTR, "scsi%d: NCR5380 interrupt, DMA status = %02x\n",
-		   atari_scsi_host->host_no, dma_stat & 0xff);
+	dsprintk(NDEBUG_INTR, instance, "NCR5380 interrupt, DMA status = %02x\n",
+	         dma_stat & 0xff);
 
 	/* Look if it was the DMA that has interrupted: First possibility
 	 * is that a bus error occurred...
@@ -293,7 +291,8 @@ static irqreturn_t scsi_tt_intr(int irq,
 	 * data reg!
 	 */
 	if ((dma_stat & 0x02) && !(dma_stat & 0x40)) {
-		atari_dma_residual = HOSTDATA_DMALEN - (SCSI_DMA_READ_P(dma_addr) - atari_dma_startaddr);
+		atari_dma_residual = hostdata->dma_len -
+			(SCSI_DMA_READ_P(dma_addr) - atari_dma_startaddr);
 
 		dprintk(NDEBUG_DMA, "SCSI DMA: There are %ld residual bytes.\n",
 			   atari_dma_residual);
@@ -345,15 +344,17 @@ static irqreturn_t scsi_tt_intr(int irq,
 
 #endif /* REAL_DMA */
 
-	NCR5380_intr(irq, dummy);
+	NCR5380_intr(irq, dev);
 
 	return IRQ_HANDLED;
 }
 
 
-static irqreturn_t scsi_falcon_intr(int irq, void *dummy)
+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;
 
 	/* Turn off DMA and select sector counter register before
@@ -388,7 +389,7 @@ static irqreturn_t scsi_falcon_intr(int
 			printk(KERN_ERR "SCSI DMA error: %ld bytes lost in "
 			       "ST-DMA fifo\n", transferred & 15);
 
-		atari_dma_residual = HOSTDATA_DMALEN - transferred;
+		atari_dma_residual = hostdata->dma_len - transferred;
 		dprintk(NDEBUG_DMA, "SCSI DMA: There are %ld residual bytes.\n",
 			   atari_dma_residual);
 	} else
@@ -400,13 +401,14 @@ static irqreturn_t scsi_falcon_intr(int
 		 * data to the original destination address.
 		 */
 		memcpy(atari_dma_orig_addr, phys_to_virt(atari_dma_startaddr),
-		       HOSTDATA_DMALEN - atari_dma_residual);
+		       hostdata->dma_len - atari_dma_residual);
 		atari_dma_orig_addr = NULL;
 	}
 
 #endif /* REAL_DMA */
 
-	NCR5380_intr(irq, dummy);
+	NCR5380_intr(irq, dev);
+
 	return IRQ_HANDLED;
 }
 
@@ -873,7 +875,6 @@ static int __init atari_scsi_probe(struc
 		error = -ENOMEM;
 		goto fail_alloc;
 	}
-	atari_scsi_host = instance;
 
 	instance->irq = irq->start;
 
Index: linux/drivers/scsi/sun3_scsi.c
===================================================================
--- linux.orig/drivers/scsi/sun3_scsi.c	2015-11-18 19:34:20.000000000 +1100
+++ linux/drivers/scsi/sun3_scsi.c	2015-11-18 19:34:34.000000000 +1100
@@ -56,9 +56,9 @@
 #define NCR5380_info                    sun3scsi_info
 
 #define NCR5380_dma_read_setup(instance, data, count) \
-        sun3scsi_dma_setup(data, count, 0)
+        sun3scsi_dma_setup(instance, data, count, 0)
 #define NCR5380_dma_write_setup(instance, data, count) \
-        sun3scsi_dma_setup(data, count, 1)
+        sun3scsi_dma_setup(instance, data, count, 1)
 #define NCR5380_dma_residual(instance) \
         sun3scsi_dma_residual(instance)
 #define NCR5380_dma_xfer_len(instance, cmd, phase) \
@@ -99,7 +99,6 @@ static unsigned char *sun3_dma_orig_addr
 static unsigned long sun3_dma_orig_count;
 static int sun3_dma_active;
 static unsigned long last_residual;
-static struct Scsi_Host *default_instance;
 
 /*
  * NCR 5380 register access functions
@@ -142,8 +141,9 @@ static inline void sun3_udc_write(unsign
 // safe bits for the CSR
 #define CSR_GOOD 0x060f
 
-static irqreturn_t scsi_sun3_intr(int irq, void *dummy)
+static irqreturn_t scsi_sun3_intr(int irq, void *dev)
 {
+	struct Scsi_Host *instance = dev;
 	unsigned short csr = dregs->csr;
 	int handled = 0;
 
@@ -152,46 +152,24 @@ static irqreturn_t scsi_sun3_intr(int ir
 #endif
 
 	if(csr & ~CSR_GOOD) {
-		if(csr & CSR_DMA_BUSERR) {
-			printk("scsi%d: bus error in dma\n", default_instance->host_no);
-		}
-
-		if(csr & CSR_DMA_CONFLICT) {
-			printk("scsi%d: dma conflict\n", default_instance->host_no);
-		}
+		if (csr & CSR_DMA_BUSERR)
+			shost_printk(KERN_ERR, instance, "bus error in DMA\n");
+		if (csr & CSR_DMA_CONFLICT)
+			shost_printk(KERN_ERR, instance, "DMA conflict\n");
 		handled = 1;
 	}
 
 	if(csr & (CSR_SDB_INT | CSR_DMA_INT)) {
-		NCR5380_intr(irq, dummy);
+		NCR5380_intr(irq, dev);
 		handled = 1;
 	}
 
 	return IRQ_RETVAL(handled);
 }
 
-/*
- * Debug stuff - to be called on NMI, or sysrq key. Use at your own risk; 
- * reentering NCR5380_print_status seems to have ugly side effects
- */
-
-/* this doesn't seem to get used at all -- sam */
-#if 0
-void sun3_sun3_debug (void)
-{
-	unsigned long flags;
-
-	if (default_instance) {
-			local_irq_save(flags);
-			NCR5380_print_status(default_instance);
-			local_irq_restore(flags);
-	}
-}
-#endif
-
-
 /* sun3scsi_dma_setup() -- initialize the dma controller for a read/write */
-static unsigned long sun3scsi_dma_setup(void *data, unsigned long count, int write_flag)
+static unsigned long sun3scsi_dma_setup(struct Scsi_Host *instance,
+                                void *data, unsigned long count, int write_flag)
 {
 	void *addr;
 
@@ -243,10 +221,9 @@ static unsigned long sun3scsi_dma_setup(
 	dregs->csr |= CSR_FIFO;
 	
 	if(dregs->fifo_count != count) { 
-		printk("scsi%d: fifo_mismatch %04x not %04x\n",
-		       default_instance->host_no, dregs->fifo_count,
-		       (unsigned int) count);
-		NCR5380_dprint(NDEBUG_DMA, default_instance);
+		shost_printk(KERN_ERR, instance, "FIFO mismatch %04x not %04x\n",
+		             dregs->fifo_count, (unsigned int) count);
+		NCR5380_dprint(NDEBUG_DMA, instance);
 	}
 
 	/* setup udc */
@@ -281,21 +258,6 @@ static unsigned long sun3scsi_dma_setup(
 
 }
 
-#ifndef SUN3_SCSI_VME
-static inline unsigned long sun3scsi_dma_count(struct Scsi_Host *instance)
-{
-	unsigned short resid;
-
-	dregs->udc_addr = 0x32; 
-	udelay(SUN3_DMA_DELAY);
-	resid = dregs->udc_data;
-	udelay(SUN3_DMA_DELAY);
-	resid *= 2;
-
-	return (unsigned long) resid;
-}
-#endif
-
 static inline unsigned long sun3scsi_dma_residual(struct Scsi_Host *instance)
 {
 	return last_residual;
@@ -393,7 +355,10 @@ static int sun3scsi_dma_finish(int write
 		}
 	}
 
-	count = sun3scsi_dma_count(default_instance);
+	dregs->udc_addr = 0x32;
+	udelay(SUN3_DMA_DELAY);
+	count = 2 * dregs->udc_data;
+	udelay(SUN3_DMA_DELAY);
 
 	fifo = dregs->fifo_count;
 	last_residual = fifo;
@@ -547,7 +512,6 @@ static int __init sun3_scsi_probe(struct
 		error = -ENOMEM;
 		goto fail_alloc;
 	}
-	default_instance = instance;
 
 	instance->io_port = (unsigned long)ioaddr;
 	instance->irq = irq->start;
Index: linux/drivers/scsi/atari_NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/atari_NCR5380.c	2015-11-18 19:34:33.000000000 +1100
+++ linux/drivers/scsi/atari_NCR5380.c	2015-11-18 19:34:34.000000000 +1100
@@ -1929,7 +1929,7 @@ static void NCR5380_information_transfer
 				/* 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(d, count,
+						sun3scsi_dma_setup(instance, d, count,
 						                   rq_data_dir(cmd->request));
 						sun3_dma_setup_done = cmd;
 					}
@@ -2467,7 +2467,8 @@ static void NCR5380_reselect(struct Scsi
 		}
 		/* setup this command for dma if not already */
 		if ((count >= DMA_MIN_SIZE) && (sun3_dma_setup_done != tmp)) {
-			sun3scsi_dma_setup(d, count, rq_data_dir(tmp->request));
+			sun3scsi_dma_setup(instance, d, count,
+			                   rq_data_dir(tmp->request));
 			sun3_dma_setup_done = tmp;
 		}
 	}



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

* [PATCH 65/71] atari_scsi, sun3_scsi: Remove global Scsi_Host pointer
@ 2015-11-18  8:36   ` Finn Thain
  0 siblings, 0 replies; 268+ messages in thread
From: Finn Thain @ 2015-11-18  8:36 UTC (permalink / raw)
  To: James E.J. Bottomley, Michael Schmitz, linux-m68k, linux-scsi,
	linux-kernel

[-- Attachment #1: atari_scsi-sun3_scsi-remove-global-instances --]
[-- Type: text/plain, Size: 9046 bytes --]

This refactoring removes two global Scsi_Host pointers. This
improves consistency with other ncr5380 drivers. Adopting the same
conventions as the other drivers makes them easier to read.

Signed-off-by: Finn Thain <fthain@telegraphics.com.au>

---
 drivers/scsi/atari_NCR5380.c |    5 +-
 drivers/scsi/atari_scsi.c    |   29 ++++++++---------
 drivers/scsi/sun3_scsi.c     |   72 ++++++++++---------------------------------
 3 files changed, 36 insertions(+), 70 deletions(-)

Index: linux/drivers/scsi/atari_scsi.c
===================================================================
--- linux.orig/drivers/scsi/atari_scsi.c	2015-11-18 19:34:20.000000000 +1100
+++ linux/drivers/scsi/atari_scsi.c	2015-11-18 19:34:34.000000000 +1100
@@ -159,14 +159,10 @@ static inline unsigned long SCSI_DMA_GET
 	return adr;
 }
 
-#define HOSTDATA_DMALEN		(((struct NCR5380_hostdata *) \
-				(atari_scsi_host->hostdata))->dma_len)
-
 #ifdef REAL_DMA
 static void atari_scsi_fetch_restbytes(void);
 #endif
 
-static struct Scsi_Host *atari_scsi_host;
 static unsigned char (*atari_scsi_reg_read)(unsigned char reg);
 static void (*atari_scsi_reg_write)(unsigned char reg, unsigned char value);
 
@@ -262,15 +258,17 @@ static void scsi_dma_buserr(int irq, voi
 #endif
 
 
-static irqreturn_t scsi_tt_intr(int irq, void *dummy)
+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;
 
 	dma_stat = tt_scsi_dma.dma_ctrl;
 
-	dprintk(NDEBUG_INTR, "scsi%d: NCR5380 interrupt, DMA status = %02x\n",
-		   atari_scsi_host->host_no, dma_stat & 0xff);
+	dsprintk(NDEBUG_INTR, instance, "NCR5380 interrupt, DMA status = %02x\n",
+	         dma_stat & 0xff);
 
 	/* Look if it was the DMA that has interrupted: First possibility
 	 * is that a bus error occurred...
@@ -293,7 +291,8 @@ static irqreturn_t scsi_tt_intr(int irq,
 	 * data reg!
 	 */
 	if ((dma_stat & 0x02) && !(dma_stat & 0x40)) {
-		atari_dma_residual = HOSTDATA_DMALEN - (SCSI_DMA_READ_P(dma_addr) - atari_dma_startaddr);
+		atari_dma_residual = hostdata->dma_len -
+			(SCSI_DMA_READ_P(dma_addr) - atari_dma_startaddr);
 
 		dprintk(NDEBUG_DMA, "SCSI DMA: There are %ld residual bytes.\n",
 			   atari_dma_residual);
@@ -345,15 +344,17 @@ static irqreturn_t scsi_tt_intr(int irq,
 
 #endif /* REAL_DMA */
 
-	NCR5380_intr(irq, dummy);
+	NCR5380_intr(irq, dev);
 
 	return IRQ_HANDLED;
 }
 
 
-static irqreturn_t scsi_falcon_intr(int irq, void *dummy)
+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;
 
 	/* Turn off DMA and select sector counter register before
@@ -388,7 +389,7 @@ static irqreturn_t scsi_falcon_intr(int
 			printk(KERN_ERR "SCSI DMA error: %ld bytes lost in "
 			       "ST-DMA fifo\n", transferred & 15);
 
-		atari_dma_residual = HOSTDATA_DMALEN - transferred;
+		atari_dma_residual = hostdata->dma_len - transferred;
 		dprintk(NDEBUG_DMA, "SCSI DMA: There are %ld residual bytes.\n",
 			   atari_dma_residual);
 	} else
@@ -400,13 +401,14 @@ static irqreturn_t scsi_falcon_intr(int
 		 * data to the original destination address.
 		 */
 		memcpy(atari_dma_orig_addr, phys_to_virt(atari_dma_startaddr),
-		       HOSTDATA_DMALEN - atari_dma_residual);
+		       hostdata->dma_len - atari_dma_residual);
 		atari_dma_orig_addr = NULL;
 	}
 
 #endif /* REAL_DMA */
 
-	NCR5380_intr(irq, dummy);
+	NCR5380_intr(irq, dev);
+
 	return IRQ_HANDLED;
 }
 
@@ -873,7 +875,6 @@ static int __init atari_scsi_probe(struc
 		error = -ENOMEM;
 		goto fail_alloc;
 	}
-	atari_scsi_host = instance;
 
 	instance->irq = irq->start;
 
Index: linux/drivers/scsi/sun3_scsi.c
===================================================================
--- linux.orig/drivers/scsi/sun3_scsi.c	2015-11-18 19:34:20.000000000 +1100
+++ linux/drivers/scsi/sun3_scsi.c	2015-11-18 19:34:34.000000000 +1100
@@ -56,9 +56,9 @@
 #define NCR5380_info                    sun3scsi_info
 
 #define NCR5380_dma_read_setup(instance, data, count) \
-        sun3scsi_dma_setup(data, count, 0)
+        sun3scsi_dma_setup(instance, data, count, 0)
 #define NCR5380_dma_write_setup(instance, data, count) \
-        sun3scsi_dma_setup(data, count, 1)
+        sun3scsi_dma_setup(instance, data, count, 1)
 #define NCR5380_dma_residual(instance) \
         sun3scsi_dma_residual(instance)
 #define NCR5380_dma_xfer_len(instance, cmd, phase) \
@@ -99,7 +99,6 @@ static unsigned char *sun3_dma_orig_addr
 static unsigned long sun3_dma_orig_count;
 static int sun3_dma_active;
 static unsigned long last_residual;
-static struct Scsi_Host *default_instance;
 
 /*
  * NCR 5380 register access functions
@@ -142,8 +141,9 @@ static inline void sun3_udc_write(unsign
 // safe bits for the CSR
 #define CSR_GOOD 0x060f
 
-static irqreturn_t scsi_sun3_intr(int irq, void *dummy)
+static irqreturn_t scsi_sun3_intr(int irq, void *dev)
 {
+	struct Scsi_Host *instance = dev;
 	unsigned short csr = dregs->csr;
 	int handled = 0;
 
@@ -152,46 +152,24 @@ static irqreturn_t scsi_sun3_intr(int ir
 #endif
 
 	if(csr & ~CSR_GOOD) {
-		if(csr & CSR_DMA_BUSERR) {
-			printk("scsi%d: bus error in dma\n", default_instance->host_no);
-		}
-
-		if(csr & CSR_DMA_CONFLICT) {
-			printk("scsi%d: dma conflict\n", default_instance->host_no);
-		}
+		if (csr & CSR_DMA_BUSERR)
+			shost_printk(KERN_ERR, instance, "bus error in DMA\n");
+		if (csr & CSR_DMA_CONFLICT)
+			shost_printk(KERN_ERR, instance, "DMA conflict\n");
 		handled = 1;
 	}
 
 	if(csr & (CSR_SDB_INT | CSR_DMA_INT)) {
-		NCR5380_intr(irq, dummy);
+		NCR5380_intr(irq, dev);
 		handled = 1;
 	}
 
 	return IRQ_RETVAL(handled);
 }
 
-/*
- * Debug stuff - to be called on NMI, or sysrq key. Use at your own risk; 
- * reentering NCR5380_print_status seems to have ugly side effects
- */
-
-/* this doesn't seem to get used at all -- sam */
-#if 0
-void sun3_sun3_debug (void)
-{
-	unsigned long flags;
-
-	if (default_instance) {
-			local_irq_save(flags);
-			NCR5380_print_status(default_instance);
-			local_irq_restore(flags);
-	}
-}
-#endif
-
-
 /* sun3scsi_dma_setup() -- initialize the dma controller for a read/write */
-static unsigned long sun3scsi_dma_setup(void *data, unsigned long count, int write_flag)
+static unsigned long sun3scsi_dma_setup(struct Scsi_Host *instance,
+                                void *data, unsigned long count, int write_flag)
 {
 	void *addr;
 
@@ -243,10 +221,9 @@ static unsigned long sun3scsi_dma_setup(
 	dregs->csr |= CSR_FIFO;
 	
 	if(dregs->fifo_count != count) { 
-		printk("scsi%d: fifo_mismatch %04x not %04x\n",
-		       default_instance->host_no, dregs->fifo_count,
-		       (unsigned int) count);
-		NCR5380_dprint(NDEBUG_DMA, default_instance);
+		shost_printk(KERN_ERR, instance, "FIFO mismatch %04x not %04x\n",
+		             dregs->fifo_count, (unsigned int) count);
+		NCR5380_dprint(NDEBUG_DMA, instance);
 	}
 
 	/* setup udc */
@@ -281,21 +258,6 @@ static unsigned long sun3scsi_dma_setup(
 
 }
 
-#ifndef SUN3_SCSI_VME
-static inline unsigned long sun3scsi_dma_count(struct Scsi_Host *instance)
-{
-	unsigned short resid;
-
-	dregs->udc_addr = 0x32; 
-	udelay(SUN3_DMA_DELAY);
-	resid = dregs->udc_data;
-	udelay(SUN3_DMA_DELAY);
-	resid *= 2;
-
-	return (unsigned long) resid;
-}
-#endif
-
 static inline unsigned long sun3scsi_dma_residual(struct Scsi_Host *instance)
 {
 	return last_residual;
@@ -393,7 +355,10 @@ static int sun3scsi_dma_finish(int write
 		}
 	}
 
-	count = sun3scsi_dma_count(default_instance);
+	dregs->udc_addr = 0x32;
+	udelay(SUN3_DMA_DELAY);
+	count = 2 * dregs->udc_data;
+	udelay(SUN3_DMA_DELAY);
 
 	fifo = dregs->fifo_count;
 	last_residual = fifo;
@@ -547,7 +512,6 @@ static int __init sun3_scsi_probe(struct
 		error = -ENOMEM;
 		goto fail_alloc;
 	}
-	default_instance = instance;
 
 	instance->io_port = (unsigned long)ioaddr;
 	instance->irq = irq->start;
Index: linux/drivers/scsi/atari_NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/atari_NCR5380.c	2015-11-18 19:34:33.000000000 +1100
+++ linux/drivers/scsi/atari_NCR5380.c	2015-11-18 19:34:34.000000000 +1100
@@ -1929,7 +1929,7 @@ static void NCR5380_information_transfer
 				/* 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(d, count,
+						sun3scsi_dma_setup(instance, d, count,
 						                   rq_data_dir(cmd->request));
 						sun3_dma_setup_done = cmd;
 					}
@@ -2467,7 +2467,8 @@ static void NCR5380_reselect(struct Scsi
 		}
 		/* setup this command for dma if not already */
 		if ((count >= DMA_MIN_SIZE) && (sun3_dma_setup_done != tmp)) {
-			sun3scsi_dma_setup(d, count, rq_data_dir(tmp->request));
+			sun3scsi_dma_setup(instance, d, count,
+			                   rq_data_dir(tmp->request));
 			sun3_dma_setup_done = tmp;
 		}
 	}

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

* [PATCH 66/71] ncr5380: Fix soft lockups
  2015-11-18  8:34 ` Finn Thain
@ 2015-11-18  8:36   ` Finn Thain
  -1 siblings, 0 replies; 268+ messages in thread
From: Finn Thain @ 2015-11-18  8:36 UTC (permalink / raw)
  To: James E.J. Bottomley, Michael Schmitz, linux-m68k, linux-scsi,
	linux-kernel

[-- Attachment #1: ncr5380-max_sectors --]
[-- Type: text/plain, Size: 3101 bytes --]

When exercising dmx3191d using sequential IO from dd, the driver is sent
512 KiB WRITE commands and 128 KiB READs. For a PIO transfer, the rate is
is only about 300 KiB/s, so these are long-running commands.

Because of the rudimentary design of the chip, it is necessary to poll the
SCSI bus signals during PIO and this tends to hog the CPU. The driver will
accept new commands while others execute, and this causes a soft lockup
because the workqueue item will not terminate until the issue queue is
emptied.

Fix the non-esponsiveness and soft lockup issues by calling cond_resched()
after each command is completed and by limiting the transfer size for
drivers that don't use DMA in information transfer phases.

Signed-off-by: Finn Thain <fthain@telegraphics.com.au>

---
 drivers/scsi/NCR5380.c       |   10 ++++++++--
 drivers/scsi/atari_NCR5380.c |   10 ++++++++--
 2 files changed, 16 insertions(+), 4 deletions(-)

Index: linux/drivers/scsi/NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/NCR5380.c	2015-11-18 19:34:33.000000000 +1100
+++ linux/drivers/scsi/NCR5380.c	2015-11-18 19:34:36.000000000 +1100
@@ -654,6 +654,10 @@ static int NCR5380_init(struct Scsi_Host
 
 	prepare_info(instance);
 
+#ifndef REAL_DMA
+	instance->max_sectors = 128;
+#endif
+
 	NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
 	NCR5380_write(MODE_REG, MR_BASE);
 	NCR5380_write(TARGET_COMMAND_REG, 0);
@@ -886,10 +890,10 @@ static void NCR5380_main(struct work_str
 	struct scsi_cmnd *cmd;
 	int done;
 	
-	spin_lock_irq(&hostdata->lock);
 	do {
 		done = 1;
 
+		spin_lock_irq(&hostdata->lock);
 		while (!hostdata->connected &&
 		       (cmd = dequeue_next_cmd(instance))) {
 
@@ -926,8 +930,10 @@ static void NCR5380_main(struct work_str
 			NCR5380_information_transfer(instance);
 			done = 0;
 		}
+		spin_unlock_irq(&hostdata->lock);
+		if (!done)
+			cond_resched();
 	} while (!done);
-	spin_unlock_irq(&hostdata->lock);
 }
 
 #ifndef DONT_USE_INTR
Index: linux/drivers/scsi/atari_NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/atari_NCR5380.c	2015-11-18 19:34:34.000000000 +1100
+++ linux/drivers/scsi/atari_NCR5380.c	2015-11-18 19:34:36.000000000 +1100
@@ -689,6 +689,10 @@ static int __init NCR5380_init(struct Sc
 
 	prepare_info(instance);
 
+#ifndef REAL_DMA
+	instance->max_sectors = 128;
+#endif
+
 	NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
 	NCR5380_write(MODE_REG, MR_BASE);
 	NCR5380_write(TARGET_COMMAND_REG, 0);
@@ -973,10 +977,10 @@ static void NCR5380_main(struct work_str
 	 * alter queues and touch the Falcon lock.
 	 */
 
-	spin_lock_irq(&hostdata->lock);
 	do {
 		done = 1;
 
+		spin_lock_irq(&hostdata->lock);
 		while (!hostdata->connected &&
 		       (cmd = dequeue_next_cmd(instance))) {
 
@@ -1023,8 +1027,10 @@ static void NCR5380_main(struct work_str
 			NCR5380_information_transfer(instance);
 			done = 0;
 		}
+		spin_unlock_irq(&hostdata->lock);
+		if (!done)
+			cond_resched();
 	} while (!done);
-	spin_unlock_irq(&hostdata->lock);
 }
 
 



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

* [PATCH 66/71] ncr5380: Fix soft lockups
@ 2015-11-18  8:36   ` Finn Thain
  0 siblings, 0 replies; 268+ messages in thread
From: Finn Thain @ 2015-11-18  8:36 UTC (permalink / raw)
  To: James E.J. Bottomley, Michael Schmitz, linux-m68k, linux-scsi,
	linux-kernel

[-- Attachment #1: ncr5380-max_sectors --]
[-- Type: text/plain, Size: 3101 bytes --]

When exercising dmx3191d using sequential IO from dd, the driver is sent
512 KiB WRITE commands and 128 KiB READs. For a PIO transfer, the rate is
is only about 300 KiB/s, so these are long-running commands.

Because of the rudimentary design of the chip, it is necessary to poll the
SCSI bus signals during PIO and this tends to hog the CPU. The driver will
accept new commands while others execute, and this causes a soft lockup
because the workqueue item will not terminate until the issue queue is
emptied.

Fix the non-esponsiveness and soft lockup issues by calling cond_resched()
after each command is completed and by limiting the transfer size for
drivers that don't use DMA in information transfer phases.

Signed-off-by: Finn Thain <fthain@telegraphics.com.au>

---
 drivers/scsi/NCR5380.c       |   10 ++++++++--
 drivers/scsi/atari_NCR5380.c |   10 ++++++++--
 2 files changed, 16 insertions(+), 4 deletions(-)

Index: linux/drivers/scsi/NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/NCR5380.c	2015-11-18 19:34:33.000000000 +1100
+++ linux/drivers/scsi/NCR5380.c	2015-11-18 19:34:36.000000000 +1100
@@ -654,6 +654,10 @@ static int NCR5380_init(struct Scsi_Host
 
 	prepare_info(instance);
 
+#ifndef REAL_DMA
+	instance->max_sectors = 128;
+#endif
+
 	NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
 	NCR5380_write(MODE_REG, MR_BASE);
 	NCR5380_write(TARGET_COMMAND_REG, 0);
@@ -886,10 +890,10 @@ static void NCR5380_main(struct work_str
 	struct scsi_cmnd *cmd;
 	int done;
 	
-	spin_lock_irq(&hostdata->lock);
 	do {
 		done = 1;
 
+		spin_lock_irq(&hostdata->lock);
 		while (!hostdata->connected &&
 		       (cmd = dequeue_next_cmd(instance))) {
 
@@ -926,8 +930,10 @@ static void NCR5380_main(struct work_str
 			NCR5380_information_transfer(instance);
 			done = 0;
 		}
+		spin_unlock_irq(&hostdata->lock);
+		if (!done)
+			cond_resched();
 	} while (!done);
-	spin_unlock_irq(&hostdata->lock);
 }
 
 #ifndef DONT_USE_INTR
Index: linux/drivers/scsi/atari_NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/atari_NCR5380.c	2015-11-18 19:34:34.000000000 +1100
+++ linux/drivers/scsi/atari_NCR5380.c	2015-11-18 19:34:36.000000000 +1100
@@ -689,6 +689,10 @@ static int __init NCR5380_init(struct Sc
 
 	prepare_info(instance);
 
+#ifndef REAL_DMA
+	instance->max_sectors = 128;
+#endif
+
 	NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
 	NCR5380_write(MODE_REG, MR_BASE);
 	NCR5380_write(TARGET_COMMAND_REG, 0);
@@ -973,10 +977,10 @@ static void NCR5380_main(struct work_str
 	 * alter queues and touch the Falcon lock.
 	 */
 
-	spin_lock_irq(&hostdata->lock);
 	do {
 		done = 1;
 
+		spin_lock_irq(&hostdata->lock);
 		while (!hostdata->connected &&
 		       (cmd = dequeue_next_cmd(instance))) {
 
@@ -1023,8 +1027,10 @@ static void NCR5380_main(struct work_str
 			NCR5380_information_transfer(instance);
 			done = 0;
 		}
+		spin_unlock_irq(&hostdata->lock);
+		if (!done)
+			cond_resched();
 	} while (!done);
-	spin_unlock_irq(&hostdata->lock);
 }
 
 



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

* [PATCH 67/71] ncr5380: Cleanup comments
  2015-11-18  8:34 ` Finn Thain
@ 2015-11-18  8:36   ` Finn Thain
  -1 siblings, 0 replies; 268+ messages in thread
From: Finn Thain @ 2015-11-18  8:36 UTC (permalink / raw)
  To: James E.J. Bottomley, Michael Schmitz, linux-m68k, linux-scsi,
	linux-kernel

[-- Attachment #1: ncr5380-cleanup-comments --]
[-- Type: text/plain, Size: 19217 bytes --]

The CVS revision log is not nearly as useful as the history/history.git
repo, so remove it. Roman's commentary at the top of his driver repeats
the same information elsewhere in the file so remove it. Also remove
some other redundant or obsolete comments.

Both the driver and the datasheets confusingly refer to a DMA access
for a SCSI WRITE command as a "DMA write". Similarly a SCSI READ command
is called a "DMA read". This is the opposite of the usual convention.
Thankfully, the chip documentation and driver code also use "DMA send" and
"DMA receive", so adopt this terminology.

This removes some unimportant discrepancies between the two core driver
forks so that 'diff' can be used to reveal the important ones, to
facilitate reunification.

Signed-off-by: Finn Thain <fthain@telegraphics.com.au>

---
 drivers/scsi/NCR5380.c       |  154 ++++++++++---------------------------------
 drivers/scsi/atari_NCR5380.c |   97 +++------------------------
 2 files changed, 48 insertions(+), 203 deletions(-)

Index: linux/drivers/scsi/NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/NCR5380.c	2015-11-18 19:34:36.000000000 +1100
+++ linux/drivers/scsi/NCR5380.c	2015-11-18 19:34:37.000000000 +1100
@@ -25,45 +25,8 @@
  */
 
 /*
- * Revision 1.10 1998/9/2	Alan Cox
- *				(alan@lxorguk.ukuu.org.uk)
- * Fixed up the timer lockups reported so far. Things still suck. Looking 
- * forward to 2.3 and per device request queues. Then it'll be possible to
- * SMP thread this beast and improve life no end.
- 
- * Revision 1.9  1997/7/27	Ronald van Cuijlenborg
- *				(ronald.van.cuijlenborg@tip.nl or nutty@dds.nl)
- * (hopefully) fixed and enhanced USLEEP
- * added support for DTC3181E card (for Mustek scanner)
- *
-
- * Revision 1.8			Ingmar Baumgart
- *				(ingmar@gonzo.schwaben.de)
- * added support for NCR53C400a card
- *
-
- * Revision 1.7  1996/3/2       Ray Van Tassle (rayvt@comm.mot.com)
- * added proc_info
- * added support needed for DTC 3180/3280
- * fixed a couple of bugs
- *
-
- * Revision 1.5  1994/01/19  09:14:57  drew
- * Fixed udelay() hack that was being used on DATAOUT phases
- * instead of a proper wait for the final handshake.
- *
- * Revision 1.4  1994/01/19  06:44:25  drew
- * *** empty log message ***
- *
- * Revision 1.3  1994/01/19  05:24:40  drew
- * Added support for TCR LAST_BYTE_SENT bit.
- *
- * Revision 1.2  1994/01/15  06:14:11  drew
- * REAL DMA support, bug fixes.
- *
- * Revision 1.1  1994/01/15  06:00:54  drew
- * Initial revision
- *
+ * With contributions from Ray Van Tassle, Ingmar Baumgart,
+ * Ronald van Cuijlenborg, Alan Cox and others.
  */
 
 /*
@@ -98,12 +61,6 @@
  * transfer - some PC's will use the I/O bus, 68K's must use 
  * memory mapped) and drops this file in their 'C' wrapper.
  *
- * (Note from hch:  unfortunately it was not enough for the different
- * m68k folks and instead of improving this driver they copied it
- * and hacked it up for their needs.  As a consequence they lost
- * most updates to this driver.  Maybe someone will fix all these
- * drivers to use a common core one day..)
- *
  * 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 
@@ -180,9 +137,6 @@
  *      rely on phase mismatch and EOP interrupts to determine end 
  *      of phase.
  *
- * Defaults for these will be provided although the user may want to adjust 
- * these to allocate CPU resources to the SCSI driver or "real" code.
- * 
  * These macros MUST be defined :
  * 
  * NCR5380_read(register)  - read from the specified register
@@ -219,7 +173,7 @@
 static int do_abort(struct Scsi_Host *);
 static void do_reset(struct Scsi_Host *);
 
-/*
+/**
  *	initialize_SCp		-	init the scsi pointer field
  *	@cmd: command block to set up
  *
@@ -379,8 +333,6 @@ mrs[] = {
  *	@instance:	adapter state to dump
  *
  *	Print the SCSI bus signals for debugging purposes
- *
- *	Locks: caller holds hostdata lock (not essential)
  */
 
 static void NCR5380_print(struct Scsi_Host *instance)
@@ -413,13 +365,11 @@ static void NCR5380_print(struct Scsi_Ho
 }
 
 
-/* 
+/**
  *	NCR5380_print_phase	-	show SCSI phase
  *	@instance: adapter to dump
  *
  * 	Print the current SCSI phase for debugging purposes
- *
- *	Locks: none
  */
 
 static void NCR5380_print_phase(struct Scsi_Host *instance)
@@ -463,8 +413,6 @@ static irqreturn_t __init probe_intr(int
  *
  *	Autoprobe for the IRQ line used by the NCR5380 by triggering an IRQ
  *	and then looking to see what interrupt actually turned up.
- *
- *	Locks: none, irqs must be enabled on entry
  */
 
 static int __init __maybe_unused NCR5380_probe_irq(struct Scsi_Host *instance,
@@ -514,8 +462,6 @@ static int __init __maybe_unused NCR5380
  *	@instance: relevant scsi host instance
  *
  *	For use as the host template info() handler.
- *
- *	Locks: none
  */
 
 static const char *NCR5380_info(struct Scsi_Host *instance)
@@ -566,20 +512,6 @@ static void prepare_info(struct Scsi_Hos
 }
 
 #ifdef PSEUDO_DMA
-/******************************************/
-/*
- * /proc/scsi/[dtc pas16 t128 generic]/[0-ASC_NUM_BOARD_SUPPORTED]
- *
- * *buffer: I/O buffer
- * **start: if inout == FALSE pointer into buffer where user read should start
- * offset: current offset
- * length: length of buffer
- * hostno: Scsi_Host host_no
- * inout: TRUE - user is writing; FALSE - user is reading
- *
- * Return the number of bytes read from or written
- */
-
 static int __maybe_unused NCR5380_write_info(struct Scsi_Host *instance,
 	char *buffer, int length)
 {
@@ -613,8 +545,6 @@ static int __maybe_unused NCR5380_show_i
  *      set correctly.  I don't care about the irq and other fields. 
  *
  *	Returns 0 for success
- *
- *	Locks: interrupts must be enabled when we are called 
  */
 
 static int NCR5380_init(struct Scsi_Host *instance, int flags)
@@ -877,9 +807,6 @@ static void requeue_cmd(struct Scsi_Host
  *      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.
- * 
- *	Locks: called as its own thread with no locks held. Takes the
- *	host lock and called routines may take the isa dma lock.
  */
 
 static void NCR5380_main(struct work_struct *work)
@@ -1077,8 +1004,6 @@ static irqreturn_t NCR5380_intr(int irq,
  *
  *      If failed (no target) : cmd->scsi_done() will be called, and the 
  *              cmd->result host byte set to DID_BAD_TARGET.
- *
- *	Locks: caller holds hostdata lock in IRQ mode
  */
  
 static struct scsi_cmnd *NCR5380_select(struct Scsi_Host *instance,
@@ -1578,8 +1503,6 @@ timeout:
  *      is in same phase.
  *
  *      Also, *phase, *count, *data are modified in place.
- *
- *	Locks: io_request lock held by caller
  */
 
 
@@ -1656,39 +1579,38 @@ static int NCR5380_transfer_dma(struct S
 	} 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).
-
-   For write DMAs, we want to wait until the last byte has been
-   transferred out over the bus before we turn off DMA mode.  Alas, there
-   seems to be no terribly good way of doing this on a 5380 under all
-   conditions.  For non-scatter-gather operations, we can wait until REQ
-   and ACK both go false, or until a phase mismatch occurs.  Gather-writes
-   are nastier, since the device will be expecting more data than we
-   are prepared to send it, and REQ will remain asserted.  On a 53C8[01] we
-   could test LAST BIT SENT to assure transfer (I imagine this is precisely
-   why this signal was added to the newer chips) but on the older 538[01]
-   this signal does not exist.  The workaround for this lack is a watchdog;
-   we bail out of the wait-loop after a modest amount of wait-time if
-   the usual exit conditions are not met.  Not a terribly clean or
-   correct solution :-%
-
-   Reads are equally tricky due to a nasty characteristic of the NCR5380.
-   If the chip is in DMA mode for an READ, it will respond to a target's
-   REQ by latching the SCSI data into the INPUT DATA register and asserting
-   ACK, even if it has _already_ been notified by the DMA controller that
-   the current DMA transfer has completed!  If the NCR5380 is then taken
-   out of DMA mode, this already-acknowledged byte is lost.
-
-   This is not a problem for "one DMA transfer per command" reads, because
-   the situation will never arise... either all of the data is DMA'ed
-   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-reads, we must work around the
-   problem.  The chosen fix is to DMA N-2 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.
+ * 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).
+ *
+ * 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
+ * seems to be no terribly good way of doing this on a 5380 under all
+ * conditions.  For non-scatter-gather operations, we can wait until REQ
+ * and ACK both go false, or until a phase mismatch occurs.  Gather-sends
+ * are nastier, since the device will be expecting more data than we
+ * are prepared to send it, and REQ will remain asserted.  On a 53C8[01] we
+ * could test Last Byte Sent to assure transfer (I imagine this is precisely
+ * why this signal was added to the newer chips) but on the older 538[01]
+ * this signal does not exist.  The workaround for this lack is a watchdog;
+ * we bail out of the wait-loop after a modest amount of wait-time if
+ * the usual exit conditions are not met.  Not a terribly clean or
+ * correct solution :-%
+ *
+ * DMA receive is equally tricky due to a nasty characteristic of the NCR5380.
+ * If the chip is in DMA receive mode, it will respond to a target's
+ * REQ by latching the SCSI data into the INPUT DATA register and asserting
+ * ACK, even if it has _already_ been notified by the DMA controller that
+ * the current DMA transfer has completed!  If the NCR5380 is then taken
+ * out of DMA mode, this already-acknowledged byte is lost. This is
+ * not a problem for "one DMA transfer per READ command", because
+ * the situation will never arise... either all of the data is DMA'ed
+ * 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
+ * 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) {
@@ -1824,8 +1746,6 @@ static int NCR5380_transfer_dma(struct S
  *
  * XXX Note : we need to watch for bus free or a reset condition here 
  *      to recover from an unexpected bus free condition.
- *
- * Locks: io_request_lock held by caller in IRQ mode
  */
 
 static void NCR5380_information_transfer(struct Scsi_Host *instance) {
@@ -2153,8 +2073,6 @@ static void NCR5380_information_transfer
  *      nexus has been reestablished,
  *      
  * Inputs : instance - this instance of the NCR5380.
- *
- * Locks: io_request_lock held by caller if IRQ driven
  */
 
 static void NCR5380_reselect(struct Scsi_Host *instance) {
Index: linux/drivers/scsi/atari_NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/atari_NCR5380.c	2015-11-18 19:34:36.000000000 +1100
+++ linux/drivers/scsi/atari_NCR5380.c	2015-11-18 19:34:37.000000000 +1100
@@ -24,47 +24,7 @@
  * 1+ (800) 334-5454
  */
 
-/*
- * ++roman: To port the 5380 driver to the Atari, I had to do some changes in
- * this file, too:
- *
- *  - Some of the debug statements were incorrect (undefined variables and the
- *    like). I fixed that.
- *
- *  - In information_transfer(), I think a #ifdef was wrong. Looking at the
- *    possible DMA transfer size should also happen for REAL_DMA. I added this
- *    in the #if statement.
- *
- *  - When using real DMA, information_transfer() should return in a DATAOUT
- *    phase after starting the DMA. It has nothing more to do.
- *
- *  - The interrupt service routine should run main after end of DMA, too (not
- *    only after RESELECTION interrupts). Additionally, it should _not_ test
- *    for more interrupts after running main, since a DMA process may have
- *    been started and interrupts are turned on now. The new int could happen
- *    inside the execution of NCR5380_intr(), leading to recursive
- *    calls.
- *
- *  - I've added a function merge_contiguous_buffers() that tries to
- *    merge scatter-gather buffers that are located at contiguous
- *    physical addresses and can be processed with the same DMA setup.
- *    Since most scatter-gather operations work on a page (4K) of
- *    4 buffers (1K), in more than 90% of all cases three interrupts and
- *    DMA setup actions are saved.
- *
- * - I've deleted all the stuff for AUTOPROBE_IRQ, REAL_DMA_POLL, PSEUDO_DMA
- *    and USLEEP, because these were messing up readability and will never be
- *    needed for Atari SCSI.
- *
- * - I've revised the NCR5380_main() calling scheme (relax the 'main_running'
- *   stuff), and 'main' is executed in a bottom half if awoken by an
- *   interrupt.
- *
- * - The code was quite cluttered up by "#if (NDEBUG & NDEBUG_*) printk..."
- *   constructs. In my eyes, this made the source rather unreadable, so I
- *   finally replaced that by the *_PRINTK() macros.
- *
- */
+/* Ported to Atari by Roman Hodek and others. */
 
 /* Adapted for the sun3 by Sam Creasey. */
 
@@ -344,17 +304,15 @@ static void free_all_tags(struct NCR5380
 
 #endif /* SUPPORT_TAGS */
 
-
-/*
- * Function: void merge_contiguous_buffers( struct scsi_cmnd *cmd )
+/**
+ * merge_contiguous_buffers - coalesce scatter-gather list entries
+ * @cmd: command requesting IO
  *
- * Purpose: Try to merge several scatter-gather requests into one DMA
- *    transfer. This is possible if the scatter buffers lie on
- *    physical contiguous addresses.
- *
- * Parameters: struct scsi_cmnd *cmd
- *    The command to work on. The first scatter buffer's data are
- *    assumed to be already transferred into ptr/this_residual.
+ * 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)
@@ -406,9 +364,7 @@ static inline void initialize_SCp(struct
 		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;
-		/* ++roman: Try to merge some scatter-buffers if they are at
-		 * contiguous physical addresses.
-		 */
+
 		merge_contiguous_buffers(cmd);
 	} else {
 		cmd->SCp.buffer = NULL;
@@ -567,8 +523,6 @@ static struct {
  * @instance: adapter to dump
  *
  * Print the current SCSI phase for debugging purposes
- *
- * Locks: none
  */
 
 static void NCR5380_print_phase(struct Scsi_Host *instance)
@@ -594,8 +548,6 @@ static void NCR5380_print_phase(struct S
  * @instance: relevant scsi host instance
  *
  * For use as the host template info() handler.
- *
- * Locks: none
  */
 
 static const char *NCR5380_info(struct Scsi_Host *instance)
@@ -830,20 +782,6 @@ static int NCR5380_queue_command(struct
 	cmd->result = 0;
 
 	/*
-	 * 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.
-	 */
-
-	/* ++guenther: now that the issue queue is being set up, we can lock ST-DMA.
-	 * Otherwise a running NCR5380_main may steal the lock.
-	 * Lock before actually inserting due to fairness reasons explained in
-	 * atari_scsi.c. If we insert first, then it's impossible for this driver
-	 * to release the lock.
-	 * Stop timer for this command while waiting for the lock, or timeouts
-	 * may happen (and they really do), and it's no good if the command doesn't
-	 * appear in any of the queues.
 	 * ++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.
@@ -959,8 +897,6 @@ static void requeue_cmd(struct Scsi_Host
  * 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.
- *
- * Locks: called as its own thread with no locks held.
  */
 
 static void NCR5380_main(struct work_struct *work)
@@ -1042,7 +978,6 @@ static void NCR5380_main(struct work_str
  *	mismatch occurs (which would finish the DMA transfer).
  *
  * Inputs : instance - this instance of the NCR5380.
- *
  */
 
 static void NCR5380_dma_complete(struct Scsi_Host *instance)
@@ -1779,7 +1714,6 @@ timeout:
  *	is in same phase.
  *
  *	Also, *phase, *count, *data are modified in place.
- *
  */
 
 
@@ -1981,9 +1915,6 @@ static void NCR5380_information_transfer
 					--cmd->SCp.buffers_residual;
 					cmd->SCp.this_residual = cmd->SCp.buffer->length;
 					cmd->SCp.ptr = sg_virt(cmd->SCp.buffer);
-					/* ++roman: Try to merge some scatter-buffers if
-					 * they are at contiguous physical addresses.
-					 */
 					merge_contiguous_buffers(cmd);
 					dsprintk(NDEBUG_INFORMATION, instance, "%d bytes and %d buffers left\n",
 					         cmd->SCp.this_residual,
@@ -2020,7 +1951,8 @@ static void NCR5380_information_transfer
 						/*
 						 * If the watchdog timer fires, all future
 						 * accesses to this device will use the
-						 * polled-IO. */
+						 * polled-IO.
+						 */
 						scmd_printk(KERN_INFO, cmd,
 							"switching to slow handshake\n");
 						cmd->device->borken = 1;
@@ -2112,10 +2044,6 @@ static void NCR5380_information_transfer
 					/* Enable reselect interrupts */
 					NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
 
-					/* ++roman: For Falcon SCSI, release the lock on the
-					 * ST-DMA here if no other commands are waiting on the
-					 * disconnected queue.
-					 */
 					maybe_release_dma_irq(instance);
 					return;
 				case MESSAGE_REJECT:
@@ -2312,7 +2240,6 @@ static void NCR5380_information_transfer
  *	nexus has been reestablished,
  *
  * Inputs : instance - this instance of the NCR5380.
- *
  */
 
 



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

* [PATCH 67/71] ncr5380: Cleanup comments
@ 2015-11-18  8:36   ` Finn Thain
  0 siblings, 0 replies; 268+ messages in thread
From: Finn Thain @ 2015-11-18  8:36 UTC (permalink / raw)
  To: James E.J. Bottomley, Michael Schmitz, linux-m68k, linux-scsi,
	linux-kernel

[-- Attachment #1: ncr5380-cleanup-comments --]
[-- Type: text/plain, Size: 19215 bytes --]

The CVS revision log is not nearly as useful as the history/history.git
repo, so remove it. Roman's commentary at the top of his driver repeats
the same information elsewhere in the file so remove it. Also remove
some other redundant or obsolete comments.

Both the driver and the datasheets confusingly refer to a DMA access
for a SCSI WRITE command as a "DMA write". Similarly a SCSI READ command
is called a "DMA read". This is the opposite of the usual convention.
Thankfully, the chip documentation and driver code also use "DMA send" and
"DMA receive", so adopt this terminology.

This removes some unimportant discrepancies between the two core driver
forks so that 'diff' can be used to reveal the important ones, to
facilitate reunification.

Signed-off-by: Finn Thain <fthain@telegraphics.com.au>

---
 drivers/scsi/NCR5380.c       |  154 ++++++++++---------------------------------
 drivers/scsi/atari_NCR5380.c |   97 +++------------------------
 2 files changed, 48 insertions(+), 203 deletions(-)

Index: linux/drivers/scsi/NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/NCR5380.c	2015-11-18 19:34:36.000000000 +1100
+++ linux/drivers/scsi/NCR5380.c	2015-11-18 19:34:37.000000000 +1100
@@ -25,45 +25,8 @@
  */
 
 /*
- * Revision 1.10 1998/9/2	Alan Cox
- *				(alan@lxorguk.ukuu.org.uk)
- * Fixed up the timer lockups reported so far. Things still suck. Looking 
- * forward to 2.3 and per device request queues. Then it'll be possible to
- * SMP thread this beast and improve life no end.
- 
- * Revision 1.9  1997/7/27	Ronald van Cuijlenborg
- *				(ronald.van.cuijlenborg@tip.nl or nutty@dds.nl)
- * (hopefully) fixed and enhanced USLEEP
- * added support for DTC3181E card (for Mustek scanner)
- *
-
- * Revision 1.8			Ingmar Baumgart
- *				(ingmar@gonzo.schwaben.de)
- * added support for NCR53C400a card
- *
-
- * Revision 1.7  1996/3/2       Ray Van Tassle (rayvt@comm.mot.com)
- * added proc_info
- * added support needed for DTC 3180/3280
- * fixed a couple of bugs
- *
-
- * Revision 1.5  1994/01/19  09:14:57  drew
- * Fixed udelay() hack that was being used on DATAOUT phases
- * instead of a proper wait for the final handshake.
- *
- * Revision 1.4  1994/01/19  06:44:25  drew
- * *** empty log message ***
- *
- * Revision 1.3  1994/01/19  05:24:40  drew
- * Added support for TCR LAST_BYTE_SENT bit.
- *
- * Revision 1.2  1994/01/15  06:14:11  drew
- * REAL DMA support, bug fixes.
- *
- * Revision 1.1  1994/01/15  06:00:54  drew
- * Initial revision
- *
+ * With contributions from Ray Van Tassle, Ingmar Baumgart,
+ * Ronald van Cuijlenborg, Alan Cox and others.
  */
 
 /*
@@ -98,12 +61,6 @@
  * transfer - some PC's will use the I/O bus, 68K's must use 
  * memory mapped) and drops this file in their 'C' wrapper.
  *
- * (Note from hch:  unfortunately it was not enough for the different
- * m68k folks and instead of improving this driver they copied it
- * and hacked it up for their needs.  As a consequence they lost
- * most updates to this driver.  Maybe someone will fix all these
- * drivers to use a common core one day..)
- *
  * 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 
@@ -180,9 +137,6 @@
  *      rely on phase mismatch and EOP interrupts to determine end 
  *      of phase.
  *
- * Defaults for these will be provided although the user may want to adjust 
- * these to allocate CPU resources to the SCSI driver or "real" code.
- * 
  * These macros MUST be defined :
  * 
  * NCR5380_read(register)  - read from the specified register
@@ -219,7 +173,7 @@
 static int do_abort(struct Scsi_Host *);
 static void do_reset(struct Scsi_Host *);
 
-/*
+/**
  *	initialize_SCp		-	init the scsi pointer field
  *	@cmd: command block to set up
  *
@@ -379,8 +333,6 @@ mrs[] = {
  *	@instance:	adapter state to dump
  *
  *	Print the SCSI bus signals for debugging purposes
- *
- *	Locks: caller holds hostdata lock (not essential)
  */
 
 static void NCR5380_print(struct Scsi_Host *instance)
@@ -413,13 +365,11 @@ static void NCR5380_print(struct Scsi_Ho
 }
 
 
-/* 
+/**
  *	NCR5380_print_phase	-	show SCSI phase
  *	@instance: adapter to dump
  *
  * 	Print the current SCSI phase for debugging purposes
- *
- *	Locks: none
  */
 
 static void NCR5380_print_phase(struct Scsi_Host *instance)
@@ -463,8 +413,6 @@ static irqreturn_t __init probe_intr(int
  *
  *	Autoprobe for the IRQ line used by the NCR5380 by triggering an IRQ
  *	and then looking to see what interrupt actually turned up.
- *
- *	Locks: none, irqs must be enabled on entry
  */
 
 static int __init __maybe_unused NCR5380_probe_irq(struct Scsi_Host *instance,
@@ -514,8 +462,6 @@ static int __init __maybe_unused NCR5380
  *	@instance: relevant scsi host instance
  *
  *	For use as the host template info() handler.
- *
- *	Locks: none
  */
 
 static const char *NCR5380_info(struct Scsi_Host *instance)
@@ -566,20 +512,6 @@ static void prepare_info(struct Scsi_Hos
 }
 
 #ifdef PSEUDO_DMA
-/******************************************/
-/*
- * /proc/scsi/[dtc pas16 t128 generic]/[0-ASC_NUM_BOARD_SUPPORTED]
- *
- * *buffer: I/O buffer
- * **start: if inout == FALSE pointer into buffer where user read should start
- * offset: current offset
- * length: length of buffer
- * hostno: Scsi_Host host_no
- * inout: TRUE - user is writing; FALSE - user is reading
- *
- * Return the number of bytes read from or written
- */
-
 static int __maybe_unused NCR5380_write_info(struct Scsi_Host *instance,
 	char *buffer, int length)
 {
@@ -613,8 +545,6 @@ static int __maybe_unused NCR5380_show_i
  *      set correctly.  I don't care about the irq and other fields. 
  *
  *	Returns 0 for success
- *
- *	Locks: interrupts must be enabled when we are called 
  */
 
 static int NCR5380_init(struct Scsi_Host *instance, int flags)
@@ -877,9 +807,6 @@ static void requeue_cmd(struct Scsi_Host
  *      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.
- * 
- *	Locks: called as its own thread with no locks held. Takes the
- *	host lock and called routines may take the isa dma lock.
  */
 
 static void NCR5380_main(struct work_struct *work)
@@ -1077,8 +1004,6 @@ static irqreturn_t NCR5380_intr(int irq,
  *
  *      If failed (no target) : cmd->scsi_done() will be called, and the 
  *              cmd->result host byte set to DID_BAD_TARGET.
- *
- *	Locks: caller holds hostdata lock in IRQ mode
  */
  
 static struct scsi_cmnd *NCR5380_select(struct Scsi_Host *instance,
@@ -1578,8 +1503,6 @@ timeout:
  *      is in same phase.
  *
  *      Also, *phase, *count, *data are modified in place.
- *
- *	Locks: io_request lock held by caller
  */
 
 
@@ -1656,39 +1579,38 @@ static int NCR5380_transfer_dma(struct S
 	} 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).
-
-   For write DMAs, we want to wait until the last byte has been
-   transferred out over the bus before we turn off DMA mode.  Alas, there
-   seems to be no terribly good way of doing this on a 5380 under all
-   conditions.  For non-scatter-gather operations, we can wait until REQ
-   and ACK both go false, or until a phase mismatch occurs.  Gather-writes
-   are nastier, since the device will be expecting more data than we
-   are prepared to send it, and REQ will remain asserted.  On a 53C8[01] we
-   could test LAST BIT SENT to assure transfer (I imagine this is precisely
-   why this signal was added to the newer chips) but on the older 538[01]
-   this signal does not exist.  The workaround for this lack is a watchdog;
-   we bail out of the wait-loop after a modest amount of wait-time if
-   the usual exit conditions are not met.  Not a terribly clean or
-   correct solution :-%
-
-   Reads are equally tricky due to a nasty characteristic of the NCR5380.
-   If the chip is in DMA mode for an READ, it will respond to a target's
-   REQ by latching the SCSI data into the INPUT DATA register and asserting
-   ACK, even if it has _already_ been notified by the DMA controller that
-   the current DMA transfer has completed!  If the NCR5380 is then taken
-   out of DMA mode, this already-acknowledged byte is lost.
-
-   This is not a problem for "one DMA transfer per command" reads, because
-   the situation will never arise... either all of the data is DMA'ed
-   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-reads, we must work around the
-   problem.  The chosen fix is to DMA N-2 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.
+ * 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).
+ *
+ * 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
+ * seems to be no terribly good way of doing this on a 5380 under all
+ * conditions.  For non-scatter-gather operations, we can wait until REQ
+ * and ACK both go false, or until a phase mismatch occurs.  Gather-sends
+ * are nastier, since the device will be expecting more data than we
+ * are prepared to send it, and REQ will remain asserted.  On a 53C8[01] we
+ * could test Last Byte Sent to assure transfer (I imagine this is precisely
+ * why this signal was added to the newer chips) but on the older 538[01]
+ * this signal does not exist.  The workaround for this lack is a watchdog;
+ * we bail out of the wait-loop after a modest amount of wait-time if
+ * the usual exit conditions are not met.  Not a terribly clean or
+ * correct solution :-%
+ *
+ * DMA receive is equally tricky due to a nasty characteristic of the NCR5380.
+ * If the chip is in DMA receive mode, it will respond to a target's
+ * REQ by latching the SCSI data into the INPUT DATA register and asserting
+ * ACK, even if it has _already_ been notified by the DMA controller that
+ * the current DMA transfer has completed!  If the NCR5380 is then taken
+ * out of DMA mode, this already-acknowledged byte is lost. This is
+ * not a problem for "one DMA transfer per READ command", because
+ * the situation will never arise... either all of the data is DMA'ed
+ * 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
+ * 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) {
@@ -1824,8 +1746,6 @@ static int NCR5380_transfer_dma(struct S
  *
  * XXX Note : we need to watch for bus free or a reset condition here 
  *      to recover from an unexpected bus free condition.
- *
- * Locks: io_request_lock held by caller in IRQ mode
  */
 
 static void NCR5380_information_transfer(struct Scsi_Host *instance) {
@@ -2153,8 +2073,6 @@ static void NCR5380_information_transfer
  *      nexus has been reestablished,
  *      
  * Inputs : instance - this instance of the NCR5380.
- *
- * Locks: io_request_lock held by caller if IRQ driven
  */
 
 static void NCR5380_reselect(struct Scsi_Host *instance) {
Index: linux/drivers/scsi/atari_NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/atari_NCR5380.c	2015-11-18 19:34:36.000000000 +1100
+++ linux/drivers/scsi/atari_NCR5380.c	2015-11-18 19:34:37.000000000 +1100
@@ -24,47 +24,7 @@
  * 1+ (800) 334-5454
  */
 
-/*
- * ++roman: To port the 5380 driver to the Atari, I had to do some changes in
- * this file, too:
- *
- *  - Some of the debug statements were incorrect (undefined variables and the
- *    like). I fixed that.
- *
- *  - In information_transfer(), I think a #ifdef was wrong. Looking at the
- *    possible DMA transfer size should also happen for REAL_DMA. I added this
- *    in the #if statement.
- *
- *  - When using real DMA, information_transfer() should return in a DATAOUT
- *    phase after starting the DMA. It has nothing more to do.
- *
- *  - The interrupt service routine should run main after end of DMA, too (not
- *    only after RESELECTION interrupts). Additionally, it should _not_ test
- *    for more interrupts after running main, since a DMA process may have
- *    been started and interrupts are turned on now. The new int could happen
- *    inside the execution of NCR5380_intr(), leading to recursive
- *    calls.
- *
- *  - I've added a function merge_contiguous_buffers() that tries to
- *    merge scatter-gather buffers that are located at contiguous
- *    physical addresses and can be processed with the same DMA setup.
- *    Since most scatter-gather operations work on a page (4K) of
- *    4 buffers (1K), in more than 90% of all cases three interrupts and
- *    DMA setup actions are saved.
- *
- * - I've deleted all the stuff for AUTOPROBE_IRQ, REAL_DMA_POLL, PSEUDO_DMA
- *    and USLEEP, because these were messing up readability and will never be
- *    needed for Atari SCSI.
- *
- * - I've revised the NCR5380_main() calling scheme (relax the 'main_running'
- *   stuff), and 'main' is executed in a bottom half if awoken by an
- *   interrupt.
- *
- * - The code was quite cluttered up by "#if (NDEBUG & NDEBUG_*) printk..."
- *   constructs. In my eyes, this made the source rather unreadable, so I
- *   finally replaced that by the *_PRINTK() macros.
- *
- */
+/* Ported to Atari by Roman Hodek and others. */
 
 /* Adapted for the sun3 by Sam Creasey. */
 
@@ -344,17 +304,15 @@ static void free_all_tags(struct NCR5380
 
 #endif /* SUPPORT_TAGS */
 
-
-/*
- * Function: void merge_contiguous_buffers( struct scsi_cmnd *cmd )
+/**
+ * merge_contiguous_buffers - coalesce scatter-gather list entries
+ * @cmd: command requesting IO
  *
- * Purpose: Try to merge several scatter-gather requests into one DMA
- *    transfer. This is possible if the scatter buffers lie on
- *    physical contiguous addresses.
- *
- * Parameters: struct scsi_cmnd *cmd
- *    The command to work on. The first scatter buffer's data are
- *    assumed to be already transferred into ptr/this_residual.
+ * 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)
@@ -406,9 +364,7 @@ static inline void initialize_SCp(struct
 		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;
-		/* ++roman: Try to merge some scatter-buffers if they are at
-		 * contiguous physical addresses.
-		 */
+
 		merge_contiguous_buffers(cmd);
 	} else {
 		cmd->SCp.buffer = NULL;
@@ -567,8 +523,6 @@ static struct {
  * @instance: adapter to dump
  *
  * Print the current SCSI phase for debugging purposes
- *
- * Locks: none
  */
 
 static void NCR5380_print_phase(struct Scsi_Host *instance)
@@ -594,8 +548,6 @@ static void NCR5380_print_phase(struct S
  * @instance: relevant scsi host instance
  *
  * For use as the host template info() handler.
- *
- * Locks: none
  */
 
 static const char *NCR5380_info(struct Scsi_Host *instance)
@@ -830,20 +782,6 @@ static int NCR5380_queue_command(struct
 	cmd->result = 0;
 
 	/*
-	 * 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.
-	 */
-
-	/* ++guenther: now that the issue queue is being set up, we can lock ST-DMA.
-	 * Otherwise a running NCR5380_main may steal the lock.
-	 * Lock before actually inserting due to fairness reasons explained in
-	 * atari_scsi.c. If we insert first, then it's impossible for this driver
-	 * to release the lock.
-	 * Stop timer for this command while waiting for the lock, or timeouts
-	 * may happen (and they really do), and it's no good if the command doesn't
-	 * appear in any of the queues.
 	 * ++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.
@@ -959,8 +897,6 @@ static void requeue_cmd(struct Scsi_Host
  * 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.
- *
- * Locks: called as its own thread with no locks held.
  */
 
 static void NCR5380_main(struct work_struct *work)
@@ -1042,7 +978,6 @@ static void NCR5380_main(struct work_str
  *	mismatch occurs (which would finish the DMA transfer).
  *
  * Inputs : instance - this instance of the NCR5380.
- *
  */
 
 static void NCR5380_dma_complete(struct Scsi_Host *instance)
@@ -1779,7 +1714,6 @@ timeout:
  *	is in same phase.
  *
  *	Also, *phase, *count, *data are modified in place.
- *
  */
 
 
@@ -1981,9 +1915,6 @@ static void NCR5380_information_transfer
 					--cmd->SCp.buffers_residual;
 					cmd->SCp.this_residual = cmd->SCp.buffer->length;
 					cmd->SCp.ptr = sg_virt(cmd->SCp.buffer);
-					/* ++roman: Try to merge some scatter-buffers if
-					 * they are at contiguous physical addresses.
-					 */
 					merge_contiguous_buffers(cmd);
 					dsprintk(NDEBUG_INFORMATION, instance, "%d bytes and %d buffers left\n",
 					         cmd->SCp.this_residual,
@@ -2020,7 +1951,8 @@ static void NCR5380_information_transfer
 						/*
 						 * If the watchdog timer fires, all future
 						 * accesses to this device will use the
-						 * polled-IO. */
+						 * polled-IO.
+						 */
 						scmd_printk(KERN_INFO, cmd,
 							"switching to slow handshake\n");
 						cmd->device->borken = 1;
@@ -2112,10 +2044,6 @@ static void NCR5380_information_transfer
 					/* Enable reselect interrupts */
 					NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
 
-					/* ++roman: For Falcon SCSI, release the lock on the
-					 * ST-DMA here if no other commands are waiting on the
-					 * disconnected queue.
-					 */
 					maybe_release_dma_irq(instance);
 					return;
 				case MESSAGE_REJECT:
@@ -2312,7 +2240,6 @@ static void NCR5380_information_transfer
  *	nexus has been reestablished,
  *
  * Inputs : instance - this instance of the NCR5380.
- *
  */
 
 

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

* [PATCH 68/71] ncr5380: Fix whitespace issues using regexp
  2015-11-18  8:34 ` Finn Thain
@ 2015-11-18  8:36   ` Finn Thain
  -1 siblings, 0 replies; 268+ messages in thread
From: Finn Thain @ 2015-11-18  8:36 UTC (permalink / raw)
  To: James E.J. Bottomley, Michael Schmitz, linux-m68k, linux-scsi,
	linux-kernel

[-- Attachment #1: ncr5380-regexp-whitespace-fixes --]
[-- Type: text/plain, Size: 51625 bytes --]

This patch is just the result of two substitutions. The first removes any
tabs and spaces at the end of the line. The second replaces runs of
tabs and spaces at the beginning of comment lines with a single space.

perl -i -pe 's,[\t ]+$,,; s,^(\t*[/ ]\*)[ \t]+,$1 ,' drivers/scsi/{atari_,}NCR5380.c 

This removes some unimportant discrepancies between the two core driver
forks so that 'diff' can be used to reveal the important ones, to
facilitate reunification.

Signed-off-by: Finn Thain <fthain@telegraphics.com.au>

---
 drivers/scsi/NCR5380.c       |  550 +++++++++++++++++++++----------------------
 drivers/scsi/atari_NCR5380.c |  110 ++++----
 2 files changed, 330 insertions(+), 330 deletions(-)

Index: linux/drivers/scsi/NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/NCR5380.c	2015-11-18 19:34:37.000000000 +1100
+++ linux/drivers/scsi/NCR5380.c	2015-11-18 19:34:38.000000000 +1100
@@ -1,17 +1,17 @@
-/* 
+/*
  * NCR 5380 generic driver routines.  These should make it *trivial*
- *      to implement 5380 SCSI drivers under Linux with a non-trantor
- *      architecture.
+ * to implement 5380 SCSI drivers under Linux with a non-trantor
+ * architecture.
  *
- *      Note that these routines also work with NR53c400 family chips.
+ * 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
+ * Visionary Computing
+ * (Unix and Linux consulting and custom programming)
+ * drew@colorado.edu
+ * +1 (303) 666-5836
  *
- * For more information, please consult 
+ * For more information, please consult
  *
  * NCR 5380 Family
  * SCSI Protocol Controller
@@ -30,17 +30,17 @@
  */
 
 /*
- * Further development / testing that should be done : 
+ * 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.
+ * 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)
+ * 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
@@ -56,27 +56,27 @@
 /*
  * Design
  *
- * This is a generic 5380 driver.  To use it on a different platform, 
+ * 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 
+ * 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 
+ * 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 
+ * 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 : 
+ * 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 
+ * 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.
@@ -87,23 +87,23 @@
  * 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. 
+ * 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 
+ * 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 
+ * On command termination, the done function will be called as
  * appropriate.
  *
- * SCSI pointers are maintained in the SCp field of SCSI command 
+ * 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
@@ -113,48 +113,48 @@
 /*
  * 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 
+ * of chips.  To use it, you write an architecture specific functions
  * and macros and include this file in your driver.
  *
- * These macros control options : 
- * AUTOPROBE_IRQ - if defined, the NCR5380_probe_irq() function will be 
- *      defined.
- * 
+ * These macros control options :
+ * AUTOPROBE_IRQ - if defined, the NCR5380_probe_irq() function will be
+ * defined.
+ *
  * AUTOSENSE - if defined, REQUEST SENSE will be performed automatically
- *      for commands that return with a CHECK CONDITION status. 
+ * for commands that return with a CHECK CONDITION status.
  *
  * DIFFERENTIAL - if defined, NCR53c81 chips will use external differential
- *      transceivers. 
+ * transceivers.
  *
  * DONT_USE_INTR - if defined, never use interrupts, even if we probe or
- *      override-configure an IRQ.
+ * 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.
  *
  * 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.
+ * 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
  *
- * NCR5380_write(register, value) - write to the specific register 
+ * NCR5380_write(register, value) - write to the specific register
  *
- * NCR5380_implementation_fields  - additional fields needed for this 
- *      specific implementation of the NCR5380
+ * NCR5380_implementation_fields  - additional fields needed for this
+ * specific implementation of the NCR5380
  *
  * Either real DMA *or* pseudo DMA may be implemented
- * REAL functions : 
+ * 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.
+ * 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.
+ * 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
@@ -165,7 +165,7 @@
  * 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 
+ * 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.
  */
@@ -174,16 +174,16 @@ static int do_abort(struct Scsi_Host *);
 static void do_reset(struct Scsi_Host *);
 
 /**
- *	initialize_SCp		-	init the scsi pointer field
- *	@cmd: command block to set up
+ * initialize_SCp		-	init the scsi pointer field
+ * @cmd: command block to set up
  *
- *	Set up the internal fields in the SCSI command.
+ * 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 
+	/*
+	 * Initialize the Scsi Pointer field so that all of the commands in the
 	 * various queues are valid.
 	 */
 
@@ -279,12 +279,12 @@ static struct {
 	unsigned char value;
 	const char *name;
 } phases[] __maybe_unused = {
-	{PHASE_DATAOUT, "DATAOUT"}, 
-	{PHASE_DATAIN, "DATAIN"}, 
-	{PHASE_CMDOUT, "CMDOUT"}, 
-	{PHASE_STATIN, "STATIN"}, 
-	{PHASE_MSGOUT, "MSGOUT"}, 
-	{PHASE_MSGIN, "MSGIN"}, 
+	{PHASE_DATAOUT, "DATAOUT"},
+	{PHASE_DATAIN, "DATAIN"},
+	{PHASE_CMDOUT, "CMDOUT"},
+	{PHASE_STATIN, "STATIN"},
+	{PHASE_MSGOUT, "MSGOUT"},
+	{PHASE_MSGIN, "MSGIN"},
 	{PHASE_UNKNOWN, "UNKNOWN"}
 };
 
@@ -292,47 +292,47 @@ static struct {
 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"}, 
+} 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"}, 
+	{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"}, 
+},
+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_MONITOR_BSY, "MODE MONITOR BSY"}, 
-	{MR_DMA_MODE, "MODE DMA"}, 
-	{MR_ARBITRATE, "MODE ARBITRATION"}, 
+},
+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_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
+ * NCR5380_print	-	print scsi bus signals
+ * @instance:	adapter state to dump
  *
- *	Print the SCSI bus signals for debugging purposes
+ * Print the SCSI bus signals for debugging purposes
  */
 
 static void NCR5380_print(struct Scsi_Host *instance)
@@ -366,10 +366,10 @@ static void NCR5380_print(struct Scsi_Ho
 
 
 /**
- *	NCR5380_print_phase	-	show SCSI phase
- *	@instance: adapter to dump
+ * NCR5380_print_phase	-	show SCSI phase
+ * @instance: adapter to dump
  *
- * 	Print the current SCSI phase for debugging purposes
+ * Print the current SCSI phase for debugging purposes
  */
 
 static void NCR5380_print_phase(struct Scsi_Host *instance)
@@ -391,15 +391,15 @@ static void NCR5380_print_phase(struct S
 static int probe_irq __initdata;
 
 /**
- *	probe_intr	-	helper for IRQ autoprobe
- *	@irq: interrupt number
- *	@dev_id: unused
- *	@regs: unused
+ * probe_intr	-	helper for IRQ autoprobe
+ * @irq: interrupt number
+ * @dev_id: unused
+ * @regs: unused
  *
- *	Set a flag to indicate the IRQ in question was received. This is
- *	used by the IRQ probe code.
+ * Set a flag to indicate the IRQ in question was received. This is
+ * used by the IRQ probe code.
  */
- 
+
 static irqreturn_t __init probe_intr(int irq, void *dev_id)
 {
 	probe_irq = irq;
@@ -407,12 +407,12 @@ static irqreturn_t __init probe_intr(int
 }
 
 /**
- *	NCR5380_probe_irq	-	find the IRQ of an NCR5380
- *	@instance: NCR5380 controller
- *	@possible: bitmask of ISA IRQ lines
+ * NCR5380_probe_irq	-	find the IRQ of an NCR5380
+ * @instance: NCR5380 controller
+ * @possible: bitmask of ISA IRQ lines
  *
- *	Autoprobe for the IRQ line used by the NCR5380 by triggering an IRQ
- *	and then looking to see what interrupt actually turned up.
+ * Autoprobe for the IRQ line used by the NCR5380 by triggering an IRQ
+ * and then looking to see what interrupt actually turned up.
  */
 
 static int __init __maybe_unused NCR5380_probe_irq(struct Scsi_Host *instance,
@@ -431,7 +431,7 @@ static int __init __maybe_unused NCR5380
 
 	/*
 	 * A interrupt is triggered whenever BSY = false, SEL = true
-	 * and a bit set in the SELECT_ENABLE_REG is asserted on the 
+	 * and a bit set in the SELECT_ENABLE_REG is asserted on the
 	 * SCSI bus.
 	 *
 	 * Note that the bus is only driven when the phase control signals
@@ -446,7 +446,7 @@ static int __init __maybe_unused NCR5380
 
 	while (probe_irq == NO_IRQ && time_before(jiffies, timeout))
 		schedule_timeout_uninterruptible(1);
-	
+
 	NCR5380_write(SELECT_ENABLE_REG, 0);
 	NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
 
@@ -458,10 +458,10 @@ static int __init __maybe_unused NCR5380
 }
 
 /**
- *	NCR58380_info - report driver and host information
- *	@instance: relevant scsi host instance
+ * NCR58380_info - report driver and host information
+ * @instance: relevant scsi host instance
  *
- *	For use as the host template info() handler.
+ * For use as the host template info() handler.
  */
 
 static const char *NCR5380_info(struct Scsi_Host *instance)
@@ -534,17 +534,17 @@ static int __maybe_unused NCR5380_show_i
 #endif
 
 /**
- *	NCR5380_init	-	initialise an NCR5380
- *	@instance: adapter to configure
- *	@flags: control flags
+ * 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.
+ * 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. 
+ * 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
+ * Returns 0 for success
  */
 
 static int NCR5380_init(struct Scsi_Host *instance, int flags)
@@ -572,7 +572,7 @@ static int NCR5380_init(struct Scsi_Host
 	INIT_LIST_HEAD(&hostdata->disconnected);
 
 	hostdata->flags = flags;
-	
+
 	INIT_WORK(&hostdata->main_task, NCR5380_main);
 	hostdata->work_q = alloc_workqueue("ncr5380_%d",
 	                        WQ_CPU_INTENSIVE | WQ_UNBOUND | WQ_MEM_RECLAIM,
@@ -648,8 +648,8 @@ static int NCR5380_maybe_reset_bus(struc
 }
 
 /**
- *	NCR5380_exit	-	remove an NCR5380
- *	@instance: adapter to remove
+ * NCR5380_exit	-	remove an NCR5380
+ * @instance: adapter to remove
  */
 
 static void NCR5380_exit(struct Scsi_Host *instance)
@@ -720,10 +720,10 @@ static int NCR5380_queue_command(struct
 
 	spin_lock_irqsave(&hostdata->lock, flags);
 
-	/* 
-	 * Insert the cmd into the issue queue. Note that REQUEST SENSE 
+	/*
+	 * 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 
+	 * clear the contingent allegiance condition that exists and the
 	 * sense data is only guaranteed to be valid while the condition exists.
 	 */
 
@@ -801,12 +801,12 @@ static void requeue_cmd(struct Scsi_Host
 }
 
 /**
- *	NCR5380_main	-	NCR state machines
+ * 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.
+ * 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)
@@ -816,7 +816,7 @@ static void NCR5380_main(struct work_str
 	struct Scsi_Host *instance = hostdata->host;
 	struct scsi_cmnd *cmd;
 	int done;
-	
+
 	do {
 		done = 1;
 
@@ -975,37 +975,37 @@ static irqreturn_t NCR5380_intr(int irq,
 	return IRQ_RETVAL(handled);
 }
 
-#endif 
+#endif
 
-/* 
+/*
  * Function : int NCR5380_select(struct Scsi_Host *instance,
- *                               struct scsi_cmnd *cmd)
+ * 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. 
+ * 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.
  *
- * 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.
+ * 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.
+ * 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)
 {
@@ -1028,14 +1028,14 @@ static struct scsi_cmnd *NCR5380_select(
 	 */
 	hostdata->selecting = cmd;
 
-	/* 
-	 * Set the phase bits to 0, otherwise the NCR5380 won't drive the 
+	/*
+	 * 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.
 	 */
 
@@ -1092,8 +1092,8 @@ static struct scsi_cmnd *NCR5380_select(
 		spin_lock_irq(&hostdata->lock);
 		goto out;
 	}
-	/* 
-	 * Again, bus clear + bus settle time is 1.2us, however, this is 
+	/*
+	 * Again, bus clear + bus settle time is 1.2us, however, this is
 	 * a minimum so we'll udelay ceil(1.2)
 	 */
 
@@ -1116,14 +1116,14 @@ static struct scsi_cmnd *NCR5380_select(
 
 	dsprintk(NDEBUG_ARBITRATION, instance, "won arbitration\n");
 
-	/* 
-	 * Now that we have won arbitration, start Selection process, asserting 
+	/*
+	 * 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.
@@ -1132,7 +1132,7 @@ static struct scsi_cmnd *NCR5380_select(
 	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.
 	 */
@@ -1141,7 +1141,7 @@ static struct scsi_cmnd *NCR5380_select(
 	spin_unlock_irq(&hostdata->lock);
 
 	/*
-	 * The initiator shall then wait at least two deskew delays and release 
+	 * 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 */
@@ -1149,17 +1149,17 @@ static struct scsi_cmnd *NCR5380_select(
 	/* 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 
+	 * 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 
+	 * 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
@@ -1170,8 +1170,8 @@ static struct scsi_cmnd *NCR5380_select(
 
 	dsprintk(NDEBUG_SELECTION, instance, "selecting target %d\n", scmd_id(cmd));
 
-	/* 
-	 * The SCSI specification calls for a 250 ms timeout for the actual 
+	/*
+	 * The SCSI specification calls for a 250 ms timeout for the actual
 	 * selection.
 	 */
 
@@ -1202,9 +1202,9 @@ static struct scsi_cmnd *NCR5380_select(
 		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 
+	/*
+	 * 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
 	 */
 
@@ -1213,18 +1213,18 @@ static struct scsi_cmnd *NCR5380_select(
 	NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_ATN);
 
 	/*
-	 * Since we followed the SCSI spec, and raised ATN while SEL 
+	 * 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.
+	 * 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 */
@@ -1270,27 +1270,27 @@ out:
 	return cmd;
 }
 
-/* 
- * Function : int NCR5380_transfer_pio (struct Scsi_Host *instance, 
- *      unsigned char *phase, int *count, unsigned char **data)
+/*
+ * 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.
- * 
+ * 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.
+ * maximum number of bytes, 0 if all bytes or transferred or exit
+ * is in same phase.
  *
- *      Also, *phase, *count, *data are modified in place.
+ * 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 
+ * 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.
  */
@@ -1300,8 +1300,8 @@ static int NCR5380_transfer_pio(struct S
 	int c = *count;
 	unsigned char *d = *data;
 
-	/* 
-	 * The NCR5380 chip will only drive the SCSI bus when the 
+	/*
+	 * 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
 	 */
@@ -1309,9 +1309,9 @@ static int NCR5380_transfer_pio(struct S
 	 NCR5380_write(TARGET_COMMAND_REG, PHASE_SR_TO_TCR(p));
 
 	do {
-		/* 
-		 * Wait for assertion of REQ, after which the phase bits will be 
-		 * valid 
+		/*
+		 * 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)
@@ -1333,7 +1333,7 @@ static int NCR5380_transfer_pio(struct S
 
 		++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
@@ -1362,13 +1362,13 @@ static int NCR5380_transfer_pio(struct S
 		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.
+ * 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.
  */
@@ -1411,7 +1411,7 @@ static int NCR5380_transfer_pio(struct S
  * 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;
@@ -1443,12 +1443,12 @@ static int do_abort(struct Scsi_Host *in
 	/* 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 
+	/*
+	 * 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.
 	 */
@@ -1458,7 +1458,7 @@ static int do_abort(struct Scsi_Host *in
 		goto timeout;
 
 	tmp = NCR5380_read(STATUS_REG) & PHASE_MASK;
-	
+
 	NCR5380_write(TARGET_COMMAND_REG, PHASE_SR_TO_TCR(tmp));
 
 	if (tmp != PHASE_MSGOUT) {
@@ -1487,22 +1487,22 @@ timeout:
 }
 
 #if defined(REAL_DMA) || defined(PSEUDO_DMA) || defined (REAL_DMA_POLL)
-/* 
- * Function : int NCR5380_transfer_dma (struct Scsi_Host *instance, 
- *      unsigned char *phase, int *count, unsigned char **data)
+/*
+ * 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.
+ * 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.
  *
- * 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.
+ * maximum number of bytes, 0 if all bytes or transferred or exit
+ * is in same phase.
  *
- *      Also, *phase, *count, *data are modified in place.
+ * Also, *phase, *count, *data are modified in place.
  */
 
 
@@ -1544,7 +1544,7 @@ static int NCR5380_transfer_dma(struct S
 #else
 	/*
 	 * Note : on my sample board, watch-dog timeouts occurred when interrupts
-	 * were not disabled for the duration of a single DMA transfer, from 
+	 * 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.
 	 */
 
@@ -1557,9 +1557,9 @@ static int NCR5380_transfer_dma(struct S
 
 	dprintk(NDEBUG_DMA, "scsi%d : mode reg = 0x%X\n", instance->host_no, NCR5380_read(MODE_REG));
 
-	/* 
-	 *	On the PAS16 at least I/O recovery delays are not needed here.
-	 *	Everyone else seems to want them.
+	/*
+	 * On the PAS16 at least I/O recovery delays are not needed here.
+	 * Everyone else seems to want them.
 	 */
 
 	if (p & SR_IO) {
@@ -1672,24 +1672,24 @@ static int NCR5380_transfer_dma(struct S
 			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 
+			 * 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 
+			 * 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 
-			 * intended to with the pseudo-DMA read function, wait for 
+			 *
+			 * The workaround was to transfer one 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.
-			 * 
+			 *
 			 * After REQ is asserted, the NCR5380 asserts DRQ and ACK.
 			 * REQ is deasserted when ACK is asserted, and not reasserted
 			 * until ACK goes false.  Since the NCR5380 won't lower ACK
 			 * until DACK is asserted, which won't happen unless we twiddle
-			 * the DMA port or we take the NCR5380 out of DMA mode, we 
-			 * can guarantee that we won't handshake another extra 
+			 * the DMA port or we take the NCR5380 out of DMA mode, we
+			 * can guarantee that we won't handshake another extra
 			 * byte.
 			 */
 
@@ -1709,8 +1709,8 @@ static int NCR5380_transfer_dma(struct S
 		foo = NCR5380_pwrite(instance, d, c);
 		if (!foo && !(hostdata->flags & FLAG_NO_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.  
+			 * 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.
 			 */
 			if (NCR5380_poll_politely2(instance,
 			     BUS_AND_STATUS_REG, BASR_DRQ, BASR_DRQ,
@@ -1734,18 +1734,18 @@ static int NCR5380_transfer_dma(struct S
 /*
  * 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.
+ * 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.
+ * 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.
+ * 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) {
@@ -1791,7 +1791,7 @@ static void NCR5380_information_transfer
 				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.
 				 */
@@ -1806,7 +1806,7 @@ static void NCR5380_information_transfer
 					         cmd->SCp.buffers_residual);
 				}
 				/*
-				 * The preferred transfer method is going to be 
+				 * 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.
 				 *
@@ -1882,8 +1882,8 @@ static void NCR5380_information_transfer
 							complete_cmd(instance, cmd);
 					}
 
-					/* 
-					 * Restore phase bits to 0 so an interrupted selection, 
+					/*
+					 * Restore phase bits to 0 so an interrupted selection,
 					 * arbitration can resume.
 					 */
 					NCR5380_write(TARGET_COMMAND_REG, 0);
@@ -1914,8 +1914,8 @@ static void NCR5380_information_transfer
 						         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, 
+						/*
+						 * Restore phase bits to 0 so an interrupted selection,
 						 * arbitration can resume.
 						 */
 						NCR5380_write(TARGET_COMMAND_REG, 0);
@@ -1924,14 +1924,14 @@ static void NCR5380_information_transfer
 						NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
 						return;
 					}
-					/* 
+					/*
 					 * The SCSI data pointer is *IMPLICITLY* saved on a disconnect
-					 * operation, in violation of the SCSI spec so we can safely 
+					 * operation, in violation of the SCSI spec so we can safely
 					 * ignore SAVE/RESTORE pointers calls.
 					 *
-					 * Unfortunately, some disks violate the SCSI spec and 
+					 * 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 
+					 * disconnecting, and we have to break spec to remain
 					 * compatible.
 					 */
 				case SAVE_POINTERS:
@@ -1940,17 +1940,17 @@ static void NCR5380_information_transfer
 					NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
 					break;
 				case EXTENDED_MESSAGE:
-/* 
+/*
  * Extended messages are sent in the following format :
- * Byte         
+ * Byte
  * 0            EXTENDED_MESSAGE == 1
- * 1            length (includes one byte for code, doesn't 
- *              include first two bytes)
+ * 1            length (includes one byte for code, doesn't
+ * include first two bytes)
  * 2            code
  * 3..length+1  arguments
  *
  * Start the extended message buffer with the EXTENDED_MESSAGE
- * byte, since spi_print_msg() wants the whole thing.  
+ * byte, since spi_print_msg() wants the whole thing.
  */
 					extended_msg[0] = EXTENDED_MESSAGE;
 					/* Accept first byte by clearing ACK */
@@ -2002,8 +2002,8 @@ static void NCR5380_information_transfer
 
 					/* Fall through to reject message */
 
-					/* 
-					 * If we get something weird that we aren't expecting, 
+					/*
+					 * If we get something weird that we aren't expecting,
 					 * reject it.
 					 */
 				default:
@@ -2040,10 +2040,10 @@ static void NCR5380_information_transfer
 			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.  
+				/*
+				 * 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;
@@ -2068,10 +2068,10 @@ static void NCR5380_information_transfer
 /*
  * 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,
- *      
+ * 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.
  */
 
@@ -2096,7 +2096,7 @@ static void NCR5380_reselect(struct Scsi
 
 	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).
@@ -2191,12 +2191,12 @@ static void NCR5380_reselect(struct Scsi
  * 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).  
+ * 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.
+ * nexus has been reestablished, on failure NULL is returned.
  */
 
 #ifdef REAL_DMA
@@ -2209,7 +2209,7 @@ static void NCR5380_dma_complete(NCR5380
 	 *
 	 * Wait for final byte to transfer, ie wait for ACK to go false.
 	 *
-	 * We should use the Last Byte Sent bit, unfortunately this is 
+	 * 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
Index: linux/drivers/scsi/atari_NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/atari_NCR5380.c	2015-11-18 19:34:37.000000000 +1100
+++ linux/drivers/scsi/atari_NCR5380.c	2015-11-18 19:34:38.000000000 +1100
@@ -1,15 +1,15 @@
 /*
  * NCR 5380 generic driver routines.  These should make it *trivial*
- *	to implement 5380 SCSI drivers under Linux with a non-trantor
- *	architecture.
+ * to implement 5380 SCSI drivers under Linux with a non-trantor
+ * architecture.
  *
- *	Note that these routines also work with NR53c400 family chips.
+ * 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
+ * Visionary Computing
+ * (Unix and Linux consulting and custom programming)
+ * drew@colorado.edu
+ * +1 (303) 666-5836
  *
  * For more information, please consult
  *
@@ -93,10 +93,10 @@
  *
  * These macros control options :
  * AUTOSENSE - if defined, REQUEST SENSE will be performed automatically
- *	for commands that return with a CHECK CONDITION status.
+ * for commands that return with a CHECK CONDITION status.
  *
  * DIFFERENTIAL - if defined, NCR53c81 chips will use external differential
- *	transceivers.
+ * transceivers.
  *
  * REAL_DMA - if defined, REAL DMA is used during the data transfer phases.
  *
@@ -109,17 +109,17 @@
  * NCR5380_write(register, value) - write to the specific register
  *
  * NCR5380_implementation_fields  - additional fields needed for this
- *      specific implementation of the NCR5380
+ * 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.
+ * 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.
+ * 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
@@ -975,7 +975,7 @@ static void NCR5380_main(struct work_str
  * 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).
+ * mismatch occurs (which would finish the DMA transfer).
  *
  * Inputs : instance - this instance of the NCR5380.
  */
@@ -1162,31 +1162,31 @@ static irqreturn_t NCR5380_intr(int irq,
 
 /*
  * Function : int NCR5380_select(struct Scsi_Host *instance,
- *                               struct scsi_cmnd *cmd)
+ * 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.
+ * 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.
+ * 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 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.
+ * 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,
@@ -1411,8 +1411,8 @@ static struct scsi_cmnd *NCR5380_select(
 	 * 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.
+	 * 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 */
@@ -1474,19 +1474,19 @@ out:
 
 /*
  * Function : int NCR5380_transfer_pio (struct Scsi_Host *instance,
- *      unsigned char *phase, int *count, unsigned char **data)
+ * 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.
+ * 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.
+ * maximum number of bytes, 0 if all bytes are transferred or exit
+ * is in same phase.
  *
- *	Also, *phase, *count, *data are modified in place.
+ * Also, *phase, *count, *data are modified in place.
  *
  * XXX Note : handling for bus free may be useful.
  */
@@ -1573,11 +1573,11 @@ static int NCR5380_transfer_pio(struct S
 		/*
 		 * 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.
+		 * 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.
+		 * 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.
 		 */
@@ -1700,20 +1700,20 @@ timeout:
 #if defined(REAL_DMA)
 /*
  * Function : int NCR5380_transfer_dma (struct Scsi_Host *instance,
- *      unsigned char *phase, int *count, unsigned char **data)
+ * unsigned char *phase, int *count, unsigned char **data)
  *
  * Purpose : transfers data in given phase using either real
- *	or pseudo DMA.
+ * 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.
+ * 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.
+ * maximum number of bytes, 0 if all bytes or transferred or exit
+ * is in same phase.
  *
- *	Also, *phase, *count, *data are modified in place.
+ * Also, *phase, *count, *data are modified in place.
  */
 
 
@@ -1812,17 +1812,17 @@ static int NCR5380_transfer_dma(struct S
  * 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.
+ * 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.
+ * 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.
+ * to recover from an unexpected bus free condition.
  */
 
 static void NCR5380_information_transfer(struct Scsi_Host *instance)
@@ -1932,7 +1932,7 @@ static void NCR5380_information_transfer
 				 */
 
 				/* ++roman: I suggest, this should be
-				 *   #if def(REAL_DMA)
+				 * #if def(REAL_DMA)
 				 * instead of leaving REAL_DMA out.
 				 */
 
@@ -2109,7 +2109,7 @@ static void NCR5380_information_transfer
 					 * Byte
 					 * 0		EXTENDED_MESSAGE == 1
 					 * 1		length (includes one byte for code, doesn't
-					 *		include first two bytes)
+					 * include first two bytes)
 					 * 2		code
 					 * 3..length+1	arguments
 					 *
@@ -2236,8 +2236,8 @@ static void NCR5380_information_transfer
  * 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,
+ * 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.
  */



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

* [PATCH 68/71] ncr5380: Fix whitespace issues using regexp
@ 2015-11-18  8:36   ` Finn Thain
  0 siblings, 0 replies; 268+ messages in thread
From: Finn Thain @ 2015-11-18  8:36 UTC (permalink / raw)
  To: James E.J. Bottomley, Michael Schmitz, linux-m68k, linux-scsi,
	linux-kernel

[-- Attachment #1: ncr5380-regexp-whitespace-fixes --]
[-- Type: text/plain, Size: 51623 bytes --]

This patch is just the result of two substitutions. The first removes any
tabs and spaces at the end of the line. The second replaces runs of
tabs and spaces at the beginning of comment lines with a single space.

perl -i -pe 's,[\t ]+$,,; s,^(\t*[/ ]\*)[ \t]+,$1 ,' drivers/scsi/{atari_,}NCR5380.c 

This removes some unimportant discrepancies between the two core driver
forks so that 'diff' can be used to reveal the important ones, to
facilitate reunification.

Signed-off-by: Finn Thain <fthain@telegraphics.com.au>

---
 drivers/scsi/NCR5380.c       |  550 +++++++++++++++++++++----------------------
 drivers/scsi/atari_NCR5380.c |  110 ++++----
 2 files changed, 330 insertions(+), 330 deletions(-)

Index: linux/drivers/scsi/NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/NCR5380.c	2015-11-18 19:34:37.000000000 +1100
+++ linux/drivers/scsi/NCR5380.c	2015-11-18 19:34:38.000000000 +1100
@@ -1,17 +1,17 @@
-/* 
+/*
  * NCR 5380 generic driver routines.  These should make it *trivial*
- *      to implement 5380 SCSI drivers under Linux with a non-trantor
- *      architecture.
+ * to implement 5380 SCSI drivers under Linux with a non-trantor
+ * architecture.
  *
- *      Note that these routines also work with NR53c400 family chips.
+ * 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
+ * Visionary Computing
+ * (Unix and Linux consulting and custom programming)
+ * drew@colorado.edu
+ * +1 (303) 666-5836
  *
- * For more information, please consult 
+ * For more information, please consult
  *
  * NCR 5380 Family
  * SCSI Protocol Controller
@@ -30,17 +30,17 @@
  */
 
 /*
- * Further development / testing that should be done : 
+ * 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.
+ * 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)
+ * 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
@@ -56,27 +56,27 @@
 /*
  * Design
  *
- * This is a generic 5380 driver.  To use it on a different platform, 
+ * 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 
+ * 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 
+ * 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 
+ * 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 : 
+ * 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 
+ * 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.
@@ -87,23 +87,23 @@
  * 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. 
+ * 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 
+ * 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 
+ * On command termination, the done function will be called as
  * appropriate.
  *
- * SCSI pointers are maintained in the SCp field of SCSI command 
+ * 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
@@ -113,48 +113,48 @@
 /*
  * 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 
+ * of chips.  To use it, you write an architecture specific functions
  * and macros and include this file in your driver.
  *
- * These macros control options : 
- * AUTOPROBE_IRQ - if defined, the NCR5380_probe_irq() function will be 
- *      defined.
- * 
+ * These macros control options :
+ * AUTOPROBE_IRQ - if defined, the NCR5380_probe_irq() function will be
+ * defined.
+ *
  * AUTOSENSE - if defined, REQUEST SENSE will be performed automatically
- *      for commands that return with a CHECK CONDITION status. 
+ * for commands that return with a CHECK CONDITION status.
  *
  * DIFFERENTIAL - if defined, NCR53c81 chips will use external differential
- *      transceivers. 
+ * transceivers.
  *
  * DONT_USE_INTR - if defined, never use interrupts, even if we probe or
- *      override-configure an IRQ.
+ * 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.
  *
  * 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.
+ * 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
  *
- * NCR5380_write(register, value) - write to the specific register 
+ * NCR5380_write(register, value) - write to the specific register
  *
- * NCR5380_implementation_fields  - additional fields needed for this 
- *      specific implementation of the NCR5380
+ * NCR5380_implementation_fields  - additional fields needed for this
+ * specific implementation of the NCR5380
  *
  * Either real DMA *or* pseudo DMA may be implemented
- * REAL functions : 
+ * 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.
+ * 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.
+ * 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
@@ -165,7 +165,7 @@
  * 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 
+ * 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.
  */
@@ -174,16 +174,16 @@ static int do_abort(struct Scsi_Host *);
 static void do_reset(struct Scsi_Host *);
 
 /**
- *	initialize_SCp		-	init the scsi pointer field
- *	@cmd: command block to set up
+ * initialize_SCp		-	init the scsi pointer field
+ * @cmd: command block to set up
  *
- *	Set up the internal fields in the SCSI command.
+ * 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 
+	/*
+	 * Initialize the Scsi Pointer field so that all of the commands in the
 	 * various queues are valid.
 	 */
 
@@ -279,12 +279,12 @@ static struct {
 	unsigned char value;
 	const char *name;
 } phases[] __maybe_unused = {
-	{PHASE_DATAOUT, "DATAOUT"}, 
-	{PHASE_DATAIN, "DATAIN"}, 
-	{PHASE_CMDOUT, "CMDOUT"}, 
-	{PHASE_STATIN, "STATIN"}, 
-	{PHASE_MSGOUT, "MSGOUT"}, 
-	{PHASE_MSGIN, "MSGIN"}, 
+	{PHASE_DATAOUT, "DATAOUT"},
+	{PHASE_DATAIN, "DATAIN"},
+	{PHASE_CMDOUT, "CMDOUT"},
+	{PHASE_STATIN, "STATIN"},
+	{PHASE_MSGOUT, "MSGOUT"},
+	{PHASE_MSGIN, "MSGIN"},
 	{PHASE_UNKNOWN, "UNKNOWN"}
 };
 
@@ -292,47 +292,47 @@ static struct {
 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"}, 
+} 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"}, 
+	{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"}, 
+},
+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_MONITOR_BSY, "MODE MONITOR BSY"}, 
-	{MR_DMA_MODE, "MODE DMA"}, 
-	{MR_ARBITRATE, "MODE ARBITRATION"}, 
+},
+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_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
+ * NCR5380_print	-	print scsi bus signals
+ * @instance:	adapter state to dump
  *
- *	Print the SCSI bus signals for debugging purposes
+ * Print the SCSI bus signals for debugging purposes
  */
 
 static void NCR5380_print(struct Scsi_Host *instance)
@@ -366,10 +366,10 @@ static void NCR5380_print(struct Scsi_Ho
 
 
 /**
- *	NCR5380_print_phase	-	show SCSI phase
- *	@instance: adapter to dump
+ * NCR5380_print_phase	-	show SCSI phase
+ * @instance: adapter to dump
  *
- * 	Print the current SCSI phase for debugging purposes
+ * Print the current SCSI phase for debugging purposes
  */
 
 static void NCR5380_print_phase(struct Scsi_Host *instance)
@@ -391,15 +391,15 @@ static void NCR5380_print_phase(struct S
 static int probe_irq __initdata;
 
 /**
- *	probe_intr	-	helper for IRQ autoprobe
- *	@irq: interrupt number
- *	@dev_id: unused
- *	@regs: unused
+ * probe_intr	-	helper for IRQ autoprobe
+ * @irq: interrupt number
+ * @dev_id: unused
+ * @regs: unused
  *
- *	Set a flag to indicate the IRQ in question was received. This is
- *	used by the IRQ probe code.
+ * Set a flag to indicate the IRQ in question was received. This is
+ * used by the IRQ probe code.
  */
- 
+
 static irqreturn_t __init probe_intr(int irq, void *dev_id)
 {
 	probe_irq = irq;
@@ -407,12 +407,12 @@ static irqreturn_t __init probe_intr(int
 }
 
 /**
- *	NCR5380_probe_irq	-	find the IRQ of an NCR5380
- *	@instance: NCR5380 controller
- *	@possible: bitmask of ISA IRQ lines
+ * NCR5380_probe_irq	-	find the IRQ of an NCR5380
+ * @instance: NCR5380 controller
+ * @possible: bitmask of ISA IRQ lines
  *
- *	Autoprobe for the IRQ line used by the NCR5380 by triggering an IRQ
- *	and then looking to see what interrupt actually turned up.
+ * Autoprobe for the IRQ line used by the NCR5380 by triggering an IRQ
+ * and then looking to see what interrupt actually turned up.
  */
 
 static int __init __maybe_unused NCR5380_probe_irq(struct Scsi_Host *instance,
@@ -431,7 +431,7 @@ static int __init __maybe_unused NCR5380
 
 	/*
 	 * A interrupt is triggered whenever BSY = false, SEL = true
-	 * and a bit set in the SELECT_ENABLE_REG is asserted on the 
+	 * and a bit set in the SELECT_ENABLE_REG is asserted on the
 	 * SCSI bus.
 	 *
 	 * Note that the bus is only driven when the phase control signals
@@ -446,7 +446,7 @@ static int __init __maybe_unused NCR5380
 
 	while (probe_irq == NO_IRQ && time_before(jiffies, timeout))
 		schedule_timeout_uninterruptible(1);
-	
+
 	NCR5380_write(SELECT_ENABLE_REG, 0);
 	NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
 
@@ -458,10 +458,10 @@ static int __init __maybe_unused NCR5380
 }
 
 /**
- *	NCR58380_info - report driver and host information
- *	@instance: relevant scsi host instance
+ * NCR58380_info - report driver and host information
+ * @instance: relevant scsi host instance
  *
- *	For use as the host template info() handler.
+ * For use as the host template info() handler.
  */
 
 static const char *NCR5380_info(struct Scsi_Host *instance)
@@ -534,17 +534,17 @@ static int __maybe_unused NCR5380_show_i
 #endif
 
 /**
- *	NCR5380_init	-	initialise an NCR5380
- *	@instance: adapter to configure
- *	@flags: control flags
+ * 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.
+ * 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. 
+ * 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
+ * Returns 0 for success
  */
 
 static int NCR5380_init(struct Scsi_Host *instance, int flags)
@@ -572,7 +572,7 @@ static int NCR5380_init(struct Scsi_Host
 	INIT_LIST_HEAD(&hostdata->disconnected);
 
 	hostdata->flags = flags;
-	
+
 	INIT_WORK(&hostdata->main_task, NCR5380_main);
 	hostdata->work_q = alloc_workqueue("ncr5380_%d",
 	                        WQ_CPU_INTENSIVE | WQ_UNBOUND | WQ_MEM_RECLAIM,
@@ -648,8 +648,8 @@ static int NCR5380_maybe_reset_bus(struc
 }
 
 /**
- *	NCR5380_exit	-	remove an NCR5380
- *	@instance: adapter to remove
+ * NCR5380_exit	-	remove an NCR5380
+ * @instance: adapter to remove
  */
 
 static void NCR5380_exit(struct Scsi_Host *instance)
@@ -720,10 +720,10 @@ static int NCR5380_queue_command(struct
 
 	spin_lock_irqsave(&hostdata->lock, flags);
 
-	/* 
-	 * Insert the cmd into the issue queue. Note that REQUEST SENSE 
+	/*
+	 * 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 
+	 * clear the contingent allegiance condition that exists and the
 	 * sense data is only guaranteed to be valid while the condition exists.
 	 */
 
@@ -801,12 +801,12 @@ static void requeue_cmd(struct Scsi_Host
 }
 
 /**
- *	NCR5380_main	-	NCR state machines
+ * 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.
+ * 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)
@@ -816,7 +816,7 @@ static void NCR5380_main(struct work_str
 	struct Scsi_Host *instance = hostdata->host;
 	struct scsi_cmnd *cmd;
 	int done;
-	
+
 	do {
 		done = 1;
 
@@ -975,37 +975,37 @@ static irqreturn_t NCR5380_intr(int irq,
 	return IRQ_RETVAL(handled);
 }
 
-#endif 
+#endif
 
-/* 
+/*
  * Function : int NCR5380_select(struct Scsi_Host *instance,
- *                               struct scsi_cmnd *cmd)
+ * 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. 
+ * 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.
  *
- * 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.
+ * 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.
+ * 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)
 {
@@ -1028,14 +1028,14 @@ static struct scsi_cmnd *NCR5380_select(
 	 */
 	hostdata->selecting = cmd;
 
-	/* 
-	 * Set the phase bits to 0, otherwise the NCR5380 won't drive the 
+	/*
+	 * 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.
 	 */
 
@@ -1092,8 +1092,8 @@ static struct scsi_cmnd *NCR5380_select(
 		spin_lock_irq(&hostdata->lock);
 		goto out;
 	}
-	/* 
-	 * Again, bus clear + bus settle time is 1.2us, however, this is 
+	/*
+	 * Again, bus clear + bus settle time is 1.2us, however, this is
 	 * a minimum so we'll udelay ceil(1.2)
 	 */
 
@@ -1116,14 +1116,14 @@ static struct scsi_cmnd *NCR5380_select(
 
 	dsprintk(NDEBUG_ARBITRATION, instance, "won arbitration\n");
 
-	/* 
-	 * Now that we have won arbitration, start Selection process, asserting 
+	/*
+	 * 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.
@@ -1132,7 +1132,7 @@ static struct scsi_cmnd *NCR5380_select(
 	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.
 	 */
@@ -1141,7 +1141,7 @@ static struct scsi_cmnd *NCR5380_select(
 	spin_unlock_irq(&hostdata->lock);
 
 	/*
-	 * The initiator shall then wait at least two deskew delays and release 
+	 * 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 */
@@ -1149,17 +1149,17 @@ static struct scsi_cmnd *NCR5380_select(
 	/* 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 
+	 * 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 
+	 * 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
@@ -1170,8 +1170,8 @@ static struct scsi_cmnd *NCR5380_select(
 
 	dsprintk(NDEBUG_SELECTION, instance, "selecting target %d\n", scmd_id(cmd));
 
-	/* 
-	 * The SCSI specification calls for a 250 ms timeout for the actual 
+	/*
+	 * The SCSI specification calls for a 250 ms timeout for the actual
 	 * selection.
 	 */
 
@@ -1202,9 +1202,9 @@ static struct scsi_cmnd *NCR5380_select(
 		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 
+	/*
+	 * 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
 	 */
 
@@ -1213,18 +1213,18 @@ static struct scsi_cmnd *NCR5380_select(
 	NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_ATN);
 
 	/*
-	 * Since we followed the SCSI spec, and raised ATN while SEL 
+	 * 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.
+	 * 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 */
@@ -1270,27 +1270,27 @@ out:
 	return cmd;
 }
 
-/* 
- * Function : int NCR5380_transfer_pio (struct Scsi_Host *instance, 
- *      unsigned char *phase, int *count, unsigned char **data)
+/*
+ * 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.
- * 
+ * 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.
+ * maximum number of bytes, 0 if all bytes or transferred or exit
+ * is in same phase.
  *
- *      Also, *phase, *count, *data are modified in place.
+ * 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 
+ * 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.
  */
@@ -1300,8 +1300,8 @@ static int NCR5380_transfer_pio(struct S
 	int c = *count;
 	unsigned char *d = *data;
 
-	/* 
-	 * The NCR5380 chip will only drive the SCSI bus when the 
+	/*
+	 * 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
 	 */
@@ -1309,9 +1309,9 @@ static int NCR5380_transfer_pio(struct S
 	 NCR5380_write(TARGET_COMMAND_REG, PHASE_SR_TO_TCR(p));
 
 	do {
-		/* 
-		 * Wait for assertion of REQ, after which the phase bits will be 
-		 * valid 
+		/*
+		 * 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)
@@ -1333,7 +1333,7 @@ static int NCR5380_transfer_pio(struct S
 
 		++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
@@ -1362,13 +1362,13 @@ static int NCR5380_transfer_pio(struct S
 		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.
+ * 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.
  */
@@ -1411,7 +1411,7 @@ static int NCR5380_transfer_pio(struct S
  * 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;
@@ -1443,12 +1443,12 @@ static int do_abort(struct Scsi_Host *in
 	/* 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 
+	/*
+	 * 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.
 	 */
@@ -1458,7 +1458,7 @@ static int do_abort(struct Scsi_Host *in
 		goto timeout;
 
 	tmp = NCR5380_read(STATUS_REG) & PHASE_MASK;
-	
+
 	NCR5380_write(TARGET_COMMAND_REG, PHASE_SR_TO_TCR(tmp));
 
 	if (tmp != PHASE_MSGOUT) {
@@ -1487,22 +1487,22 @@ timeout:
 }
 
 #if defined(REAL_DMA) || defined(PSEUDO_DMA) || defined (REAL_DMA_POLL)
-/* 
- * Function : int NCR5380_transfer_dma (struct Scsi_Host *instance, 
- *      unsigned char *phase, int *count, unsigned char **data)
+/*
+ * 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.
+ * 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.
  *
- * 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.
+ * maximum number of bytes, 0 if all bytes or transferred or exit
+ * is in same phase.
  *
- *      Also, *phase, *count, *data are modified in place.
+ * Also, *phase, *count, *data are modified in place.
  */
 
 
@@ -1544,7 +1544,7 @@ static int NCR5380_transfer_dma(struct S
 #else
 	/*
 	 * Note : on my sample board, watch-dog timeouts occurred when interrupts
-	 * were not disabled for the duration of a single DMA transfer, from 
+	 * 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.
 	 */
 
@@ -1557,9 +1557,9 @@ static int NCR5380_transfer_dma(struct S
 
 	dprintk(NDEBUG_DMA, "scsi%d : mode reg = 0x%X\n", instance->host_no, NCR5380_read(MODE_REG));
 
-	/* 
-	 *	On the PAS16 at least I/O recovery delays are not needed here.
-	 *	Everyone else seems to want them.
+	/*
+	 * On the PAS16 at least I/O recovery delays are not needed here.
+	 * Everyone else seems to want them.
 	 */
 
 	if (p & SR_IO) {
@@ -1672,24 +1672,24 @@ static int NCR5380_transfer_dma(struct S
 			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 
+			 * 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 
+			 * 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 
-			 * intended to with the pseudo-DMA read function, wait for 
+			 *
+			 * The workaround was to transfer one 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.
-			 * 
+			 *
 			 * After REQ is asserted, the NCR5380 asserts DRQ and ACK.
 			 * REQ is deasserted when ACK is asserted, and not reasserted
 			 * until ACK goes false.  Since the NCR5380 won't lower ACK
 			 * until DACK is asserted, which won't happen unless we twiddle
-			 * the DMA port or we take the NCR5380 out of DMA mode, we 
-			 * can guarantee that we won't handshake another extra 
+			 * the DMA port or we take the NCR5380 out of DMA mode, we
+			 * can guarantee that we won't handshake another extra
 			 * byte.
 			 */
 
@@ -1709,8 +1709,8 @@ static int NCR5380_transfer_dma(struct S
 		foo = NCR5380_pwrite(instance, d, c);
 		if (!foo && !(hostdata->flags & FLAG_NO_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.  
+			 * 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.
 			 */
 			if (NCR5380_poll_politely2(instance,
 			     BUS_AND_STATUS_REG, BASR_DRQ, BASR_DRQ,
@@ -1734,18 +1734,18 @@ static int NCR5380_transfer_dma(struct S
 /*
  * 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.
+ * 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.
+ * 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.
+ * 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) {
@@ -1791,7 +1791,7 @@ static void NCR5380_information_transfer
 				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.
 				 */
@@ -1806,7 +1806,7 @@ static void NCR5380_information_transfer
 					         cmd->SCp.buffers_residual);
 				}
 				/*
-				 * The preferred transfer method is going to be 
+				 * 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.
 				 *
@@ -1882,8 +1882,8 @@ static void NCR5380_information_transfer
 							complete_cmd(instance, cmd);
 					}
 
-					/* 
-					 * Restore phase bits to 0 so an interrupted selection, 
+					/*
+					 * Restore phase bits to 0 so an interrupted selection,
 					 * arbitration can resume.
 					 */
 					NCR5380_write(TARGET_COMMAND_REG, 0);
@@ -1914,8 +1914,8 @@ static void NCR5380_information_transfer
 						         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, 
+						/*
+						 * Restore phase bits to 0 so an interrupted selection,
 						 * arbitration can resume.
 						 */
 						NCR5380_write(TARGET_COMMAND_REG, 0);
@@ -1924,14 +1924,14 @@ static void NCR5380_information_transfer
 						NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
 						return;
 					}
-					/* 
+					/*
 					 * The SCSI data pointer is *IMPLICITLY* saved on a disconnect
-					 * operation, in violation of the SCSI spec so we can safely 
+					 * operation, in violation of the SCSI spec so we can safely
 					 * ignore SAVE/RESTORE pointers calls.
 					 *
-					 * Unfortunately, some disks violate the SCSI spec and 
+					 * 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 
+					 * disconnecting, and we have to break spec to remain
 					 * compatible.
 					 */
 				case SAVE_POINTERS:
@@ -1940,17 +1940,17 @@ static void NCR5380_information_transfer
 					NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
 					break;
 				case EXTENDED_MESSAGE:
-/* 
+/*
  * Extended messages are sent in the following format :
- * Byte         
+ * Byte
  * 0            EXTENDED_MESSAGE == 1
- * 1            length (includes one byte for code, doesn't 
- *              include first two bytes)
+ * 1            length (includes one byte for code, doesn't
+ * include first two bytes)
  * 2            code
  * 3..length+1  arguments
  *
  * Start the extended message buffer with the EXTENDED_MESSAGE
- * byte, since spi_print_msg() wants the whole thing.  
+ * byte, since spi_print_msg() wants the whole thing.
  */
 					extended_msg[0] = EXTENDED_MESSAGE;
 					/* Accept first byte by clearing ACK */
@@ -2002,8 +2002,8 @@ static void NCR5380_information_transfer
 
 					/* Fall through to reject message */
 
-					/* 
-					 * If we get something weird that we aren't expecting, 
+					/*
+					 * If we get something weird that we aren't expecting,
 					 * reject it.
 					 */
 				default:
@@ -2040,10 +2040,10 @@ static void NCR5380_information_transfer
 			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.  
+				/*
+				 * 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;
@@ -2068,10 +2068,10 @@ static void NCR5380_information_transfer
 /*
  * 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,
- *      
+ * 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.
  */
 
@@ -2096,7 +2096,7 @@ static void NCR5380_reselect(struct Scsi
 
 	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).
@@ -2191,12 +2191,12 @@ static void NCR5380_reselect(struct Scsi
  * 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).  
+ * 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.
+ * nexus has been reestablished, on failure NULL is returned.
  */
 
 #ifdef REAL_DMA
@@ -2209,7 +2209,7 @@ static void NCR5380_dma_complete(NCR5380
 	 *
 	 * Wait for final byte to transfer, ie wait for ACK to go false.
 	 *
-	 * We should use the Last Byte Sent bit, unfortunately this is 
+	 * 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
Index: linux/drivers/scsi/atari_NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/atari_NCR5380.c	2015-11-18 19:34:37.000000000 +1100
+++ linux/drivers/scsi/atari_NCR5380.c	2015-11-18 19:34:38.000000000 +1100
@@ -1,15 +1,15 @@
 /*
  * NCR 5380 generic driver routines.  These should make it *trivial*
- *	to implement 5380 SCSI drivers under Linux with a non-trantor
- *	architecture.
+ * to implement 5380 SCSI drivers under Linux with a non-trantor
+ * architecture.
  *
- *	Note that these routines also work with NR53c400 family chips.
+ * 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
+ * Visionary Computing
+ * (Unix and Linux consulting and custom programming)
+ * drew@colorado.edu
+ * +1 (303) 666-5836
  *
  * For more information, please consult
  *
@@ -93,10 +93,10 @@
  *
  * These macros control options :
  * AUTOSENSE - if defined, REQUEST SENSE will be performed automatically
- *	for commands that return with a CHECK CONDITION status.
+ * for commands that return with a CHECK CONDITION status.
  *
  * DIFFERENTIAL - if defined, NCR53c81 chips will use external differential
- *	transceivers.
+ * transceivers.
  *
  * REAL_DMA - if defined, REAL DMA is used during the data transfer phases.
  *
@@ -109,17 +109,17 @@
  * NCR5380_write(register, value) - write to the specific register
  *
  * NCR5380_implementation_fields  - additional fields needed for this
- *      specific implementation of the NCR5380
+ * 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.
+ * 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.
+ * 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
@@ -975,7 +975,7 @@ static void NCR5380_main(struct work_str
  * 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).
+ * mismatch occurs (which would finish the DMA transfer).
  *
  * Inputs : instance - this instance of the NCR5380.
  */
@@ -1162,31 +1162,31 @@ static irqreturn_t NCR5380_intr(int irq,
 
 /*
  * Function : int NCR5380_select(struct Scsi_Host *instance,
- *                               struct scsi_cmnd *cmd)
+ * 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.
+ * 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.
+ * 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 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.
+ * 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,
@@ -1411,8 +1411,8 @@ static struct scsi_cmnd *NCR5380_select(
 	 * 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.
+	 * 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 */
@@ -1474,19 +1474,19 @@ out:
 
 /*
  * Function : int NCR5380_transfer_pio (struct Scsi_Host *instance,
- *      unsigned char *phase, int *count, unsigned char **data)
+ * 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.
+ * 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.
+ * maximum number of bytes, 0 if all bytes are transferred or exit
+ * is in same phase.
  *
- *	Also, *phase, *count, *data are modified in place.
+ * Also, *phase, *count, *data are modified in place.
  *
  * XXX Note : handling for bus free may be useful.
  */
@@ -1573,11 +1573,11 @@ static int NCR5380_transfer_pio(struct S
 		/*
 		 * 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.
+		 * 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.
+		 * 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.
 		 */
@@ -1700,20 +1700,20 @@ timeout:
 #if defined(REAL_DMA)
 /*
  * Function : int NCR5380_transfer_dma (struct Scsi_Host *instance,
- *      unsigned char *phase, int *count, unsigned char **data)
+ * unsigned char *phase, int *count, unsigned char **data)
  *
  * Purpose : transfers data in given phase using either real
- *	or pseudo DMA.
+ * 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.
+ * 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.
+ * maximum number of bytes, 0 if all bytes or transferred or exit
+ * is in same phase.
  *
- *	Also, *phase, *count, *data are modified in place.
+ * Also, *phase, *count, *data are modified in place.
  */
 
 
@@ -1812,17 +1812,17 @@ static int NCR5380_transfer_dma(struct S
  * 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.
+ * 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.
+ * 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.
+ * to recover from an unexpected bus free condition.
  */
 
 static void NCR5380_information_transfer(struct Scsi_Host *instance)
@@ -1932,7 +1932,7 @@ static void NCR5380_information_transfer
 				 */
 
 				/* ++roman: I suggest, this should be
-				 *   #if def(REAL_DMA)
+				 * #if def(REAL_DMA)
 				 * instead of leaving REAL_DMA out.
 				 */
 
@@ -2109,7 +2109,7 @@ static void NCR5380_information_transfer
 					 * Byte
 					 * 0		EXTENDED_MESSAGE == 1
 					 * 1		length (includes one byte for code, doesn't
-					 *		include first two bytes)
+					 * include first two bytes)
 					 * 2		code
 					 * 3..length+1	arguments
 					 *
@@ -2236,8 +2236,8 @@ static void NCR5380_information_transfer
  * 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,
+ * 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.
  */

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

* [PATCH 69/71] ncr5380: Merge changes from atari_NCR5380.c
  2015-11-18  8:34 ` Finn Thain
@ 2015-11-18  8:36   ` Finn Thain
  -1 siblings, 0 replies; 268+ messages in thread
From: Finn Thain @ 2015-11-18  8:36 UTC (permalink / raw)
  To: James E.J. Bottomley, Michael Schmitz, linux-m68k, linux-scsi,
	linux-kernel

[-- Attachment #1: ncr5380-merge-trivia-from-atari_NCR5380 --]
[-- Type: text/plain, Size: 15037 bytes --]

In the past, NCR5380.c was overlooked by those working on atari_NCR5380.c
and this caused needless divergence. All of the changes in this patch were
taken from atari_NCR5380.c.

This removes some unimportant discrepancies between the two core driver
forks so that 'diff' can be used to reveal the important ones, to
facilitate reunification.

Signed-off-by: Finn Thain <fthain@telegraphics.com.au>

---
 drivers/scsi/NCR5380.c |  157 +++++++++++++++++++++++++++----------------------
 1 file changed, 89 insertions(+), 68 deletions(-)

Index: linux/drivers/scsi/NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/NCR5380.c	2015-11-18 19:34:38.000000000 +1100
+++ linux/drivers/scsi/NCR5380.c	2015-11-18 19:34:43.000000000 +1100
@@ -174,7 +174,7 @@ static int do_abort(struct Scsi_Host *);
 static void do_reset(struct Scsi_Host *);
 
 /**
- * initialize_SCp		-	init the scsi pointer field
+ * initialize_SCp - init the scsi pointer field
  * @cmd: command block to set up
  *
  * Set up the internal fields in the SCSI command.
@@ -275,19 +275,6 @@ static inline int NCR5380_poll_politely(
 	                                        reg, bit, val, wait);
 }
 
-static struct {
-	unsigned char value;
-	const char *name;
-} phases[] __maybe_unused = {
-	{PHASE_DATAOUT, "DATAOUT"},
-	{PHASE_DATAIN, "DATAIN"},
-	{PHASE_CMDOUT, "CMDOUT"},
-	{PHASE_STATIN, "STATIN"},
-	{PHASE_MSGOUT, "MSGOUT"},
-	{PHASE_MSGIN, "MSGIN"},
-	{PHASE_UNKNOWN, "UNKNOWN"}
-};
-
 #if NDEBUG
 static struct {
 	unsigned char mask;
@@ -322,6 +309,7 @@ mrs[] = {
 	{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"},
@@ -329,8 +317,8 @@ mrs[] = {
 };
 
 /**
- * NCR5380_print	-	print scsi bus signals
- * @instance:	adapter state to dump
+ * NCR5380_print - print scsi bus signals
+ * @instance: adapter state to dump
  *
  * Print the SCSI bus signals for debugging purposes
  */
@@ -364,9 +352,21 @@ static void NCR5380_print(struct Scsi_Ho
 	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
+ * NCR5380_print_phase - show SCSI phase
  * @instance: adapter to dump
  *
  * Print the current SCSI phase for debugging purposes
@@ -381,7 +381,9 @@ static void NCR5380_print_phase(struct S
 	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);
+		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);
 	}
 }
@@ -523,7 +525,7 @@ static int __maybe_unused NCR5380_write_
 }
 
 static int __maybe_unused NCR5380_show_info(struct seq_file *m,
-	struct Scsi_Host *instance)
+                                            struct Scsi_Host *instance)
 {
 	struct NCR5380_hostdata *hostdata = shost_priv(instance);
 
@@ -534,7 +536,7 @@ static int __maybe_unused NCR5380_show_i
 #endif
 
 /**
- * NCR5380_init	-	initialise an NCR5380
+ * NCR5380_init - initialise an NCR5380
  * @instance: adapter to configure
  * @flags: control flags
  *
@@ -542,7 +544,7 @@ static int __maybe_unused NCR5380_show_i
  * 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.
+ * set correctly. I don't care about the irq and other fields.
  *
  * Returns 0 for success
  */
@@ -552,10 +554,9 @@ static int NCR5380_init(struct Scsi_Host
 	struct NCR5380_hostdata *hostdata = shost_priv(instance);
 	int i;
 
-	if(in_interrupt())
-		printk(KERN_ERR "NCR5380_init called with interrupts off!\n");
-
+	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;
@@ -580,8 +581,6 @@ static int NCR5380_init(struct Scsi_Host
 	if (!hostdata->work_q)
 		return -ENOMEM;
 
-	hostdata->host = instance;
-
 	prepare_info(instance);
 
 #ifndef REAL_DMA
@@ -592,6 +591,7 @@ static int NCR5380_init(struct Scsi_Host
 	NCR5380_write(MODE_REG, MR_BASE);
 	NCR5380_write(TARGET_COMMAND_REG, 0);
 	NCR5380_write(SELECT_ENABLE_REG, 0);
+
 	return 0;
 }
 
@@ -648,8 +648,10 @@ static int NCR5380_maybe_reset_bus(struc
 }
 
 /**
- * NCR5380_exit	-	remove an NCR5380
+ * 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)
@@ -714,7 +716,7 @@ static int NCR5380_queue_command(struct
 		cmd->scsi_done(cmd);
 		return 0;
 	}
-#endif				/* (NDEBUG & NDEBUG_NO_WRITE) */
+#endif /* (NDEBUG & NDEBUG_NO_WRITE) */
 
 	cmd->result = 0;
 
@@ -801,7 +803,7 @@ static void requeue_cmd(struct Scsi_Host
 }
 
 /**
- * NCR5380_main	-	NCR state machines
+ * 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
@@ -1067,7 +1069,9 @@ static struct scsi_cmnd *NCR5380_select(
 	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)) {
+	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);
@@ -1092,6 +1096,7 @@ static struct scsi_cmnd *NCR5380_select(
 		spin_lock_irq(&hostdata->lock);
 		goto out;
 	}
+
 	/*
 	 * Again, bus clear + bus settle time is 1.2us, however, this is
 	 * a minimum so we'll udelay ceil(1.2)
@@ -1144,7 +1149,7 @@ static struct scsi_cmnd *NCR5380_select(
 	 * 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 */
+	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));
@@ -1281,7 +1286,7 @@ out:
  * 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
+ * maximum number of bytes, 0 if all bytes are transferred or exit
  * is in same phase.
  *
  * Also, *phase, *count, *data are modified in place.
@@ -1295,7 +1300,10 @@ out:
  * 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) {
+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;
@@ -1306,7 +1314,7 @@ static int NCR5380_transfer_pio(struct S
 	 * REGISTER match the STATUS REGISTER
 	 */
 
-	 NCR5380_write(TARGET_COMMAND_REG, PHASE_SR_TO_TCR(p));
+	NCR5380_write(TARGET_COMMAND_REG, PHASE_SR_TO_TCR(p));
 
 	do {
 		/*
@@ -1325,6 +1333,7 @@ static int NCR5380_transfer_pio(struct S
 			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);
@@ -1462,12 +1471,14 @@ static int do_abort(struct Scsi_Host *in
 	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);
+		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;
@@ -1506,7 +1517,11 @@ timeout:
  */
 
 
-static int NCR5380_transfer_dma(struct Scsi_Host *instance, unsigned char *phase, int *count, unsigned char **data) {
+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;
 	register unsigned char *d = *data;
@@ -1517,8 +1532,6 @@ static int NCR5380_transfer_dma(struct S
 	unsigned char saved_data = 0, overrun = 0, residue;
 #endif
 
-	struct NCR5380_hostdata *hostdata = shost_priv(instance);
-
 	if ((tmp = (NCR5380_read(STATUS_REG) & PHASE_MASK)) != p) {
 		*phase = tmp;
 		return -1;
@@ -1748,7 +1761,8 @@ static int NCR5380_transfer_dma(struct S
  * to recover from an unexpected bus free condition.
  */
 
-static void NCR5380_information_transfer(struct Scsi_Host *instance) {
+static void NCR5380_information_transfer(struct Scsi_Host *instance)
+{
 	struct NCR5380_hostdata *hostdata = shost_priv(instance);
 	unsigned char msgout = NOP;
 	int sink = 0;
@@ -1775,11 +1789,13 @@ static void NCR5380_information_transfer
 				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);
+				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)
@@ -1805,6 +1821,7 @@ static void NCR5380_information_transfer
 					         cmd->SCp.this_residual,
 					         cmd->SCp.buffers_residual);
 				}
+
 				/*
 				 * The preferred transfer method is going to be
 				 * PSEUDO-DMA for systems that are strictly PIO,
@@ -1823,13 +1840,15 @@ static void NCR5380_information_transfer
 
 				if (transfersize) {
 					len = transfersize;
-					if (NCR5380_transfer_dma(instance, &phase, &len, (unsigned char **) &cmd->SCp.ptr)) {
+					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.
+						 * 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");
+							"switching to slow handshake\n");
 						cmd->device->borken = 1;
 						sink = 1;
 						do_abort(instance);
@@ -1905,25 +1924,24 @@ static void NCR5380_information_transfer
 						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);
+				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);
+					/*
+					 * 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);
-						return;
-					}
+					/* Enable reselect interrupts */
+					NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
+					return;
 					/*
 					 * The SCSI data pointer is *IMPLICITLY* saved on a disconnect
 					 * operation, in violation of the SCSI spec so we can safely
@@ -2013,15 +2031,17 @@ static void NCR5380_information_transfer
 						printk("\n");
 					} else if (tmp != EXTENDED_MESSAGE)
 						scmd_printk(KERN_INFO, cmd,
-							"rejecting unknown message %02x\n",tmp);
+						            "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]);
+						            "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) */
+				} /* switch (tmp) */
 				break;
 			case PHASE_MSGOUT:
 				len = 1;
@@ -2056,7 +2076,7 @@ static void NCR5380_information_transfer
 			default:
 				shost_printk(KERN_ERR, instance, "unknown phase\n");
 				NCR5380_dprint(NDEBUG_ANY, instance);
-			}	/* switch(phase) */
+			} /* switch(phase) */
 		} else {
 			spin_unlock_irq(&hostdata->lock);
 			NCR5380_poll_politely(instance, STATUS_REG, SR_REQ, SR_REQ, HZ);
@@ -2075,7 +2095,8 @@ static void NCR5380_information_transfer
  * Inputs : instance - this instance of the NCR5380.
  */
 
-static void NCR5380_reselect(struct Scsi_Host *instance) {
+static void NCR5380_reselect(struct Scsi_Host *instance)
+{
 	struct NCR5380_hostdata *hostdata = shost_priv(instance);
 	unsigned char target_mask;
 	unsigned char lun, phase;
@@ -2172,8 +2193,8 @@ static void NCR5380_reselect(struct Scsi
 		shost_printk(KERN_ERR, instance, "target bitmask 0x%02x lun %d not in disconnected queue.\n",
 		             target_mask, lun);
 		/*
-		 * Since we have an established nexus that we can't do anything with,
-		 * we must abort it.
+		 * Since we have an established nexus that we can't do anything
+		 * with, we must abort it.
 		 */
 		do_abort(instance);
 		return;



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

* [PATCH 69/71] ncr5380: Merge changes from atari_NCR5380.c
@ 2015-11-18  8:36   ` Finn Thain
  0 siblings, 0 replies; 268+ messages in thread
From: Finn Thain @ 2015-11-18  8:36 UTC (permalink / raw)
  To: James E.J. Bottomley, Michael Schmitz, linux-m68k, linux-scsi,
	linux-kernel

[-- Attachment #1: ncr5380-merge-trivia-from-atari_NCR5380 --]
[-- Type: text/plain, Size: 15035 bytes --]

In the past, NCR5380.c was overlooked by those working on atari_NCR5380.c
and this caused needless divergence. All of the changes in this patch were
taken from atari_NCR5380.c.

This removes some unimportant discrepancies between the two core driver
forks so that 'diff' can be used to reveal the important ones, to
facilitate reunification.

Signed-off-by: Finn Thain <fthain@telegraphics.com.au>

---
 drivers/scsi/NCR5380.c |  157 +++++++++++++++++++++++++++----------------------
 1 file changed, 89 insertions(+), 68 deletions(-)

Index: linux/drivers/scsi/NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/NCR5380.c	2015-11-18 19:34:38.000000000 +1100
+++ linux/drivers/scsi/NCR5380.c	2015-11-18 19:34:43.000000000 +1100
@@ -174,7 +174,7 @@ static int do_abort(struct Scsi_Host *);
 static void do_reset(struct Scsi_Host *);
 
 /**
- * initialize_SCp		-	init the scsi pointer field
+ * initialize_SCp - init the scsi pointer field
  * @cmd: command block to set up
  *
  * Set up the internal fields in the SCSI command.
@@ -275,19 +275,6 @@ static inline int NCR5380_poll_politely(
 	                                        reg, bit, val, wait);
 }
 
-static struct {
-	unsigned char value;
-	const char *name;
-} phases[] __maybe_unused = {
-	{PHASE_DATAOUT, "DATAOUT"},
-	{PHASE_DATAIN, "DATAIN"},
-	{PHASE_CMDOUT, "CMDOUT"},
-	{PHASE_STATIN, "STATIN"},
-	{PHASE_MSGOUT, "MSGOUT"},
-	{PHASE_MSGIN, "MSGIN"},
-	{PHASE_UNKNOWN, "UNKNOWN"}
-};
-
 #if NDEBUG
 static struct {
 	unsigned char mask;
@@ -322,6 +309,7 @@ mrs[] = {
 	{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"},
@@ -329,8 +317,8 @@ mrs[] = {
 };
 
 /**
- * NCR5380_print	-	print scsi bus signals
- * @instance:	adapter state to dump
+ * NCR5380_print - print scsi bus signals
+ * @instance: adapter state to dump
  *
  * Print the SCSI bus signals for debugging purposes
  */
@@ -364,9 +352,21 @@ static void NCR5380_print(struct Scsi_Ho
 	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
+ * NCR5380_print_phase - show SCSI phase
  * @instance: adapter to dump
  *
  * Print the current SCSI phase for debugging purposes
@@ -381,7 +381,9 @@ static void NCR5380_print_phase(struct S
 	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);
+		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);
 	}
 }
@@ -523,7 +525,7 @@ static int __maybe_unused NCR5380_write_
 }
 
 static int __maybe_unused NCR5380_show_info(struct seq_file *m,
-	struct Scsi_Host *instance)
+                                            struct Scsi_Host *instance)
 {
 	struct NCR5380_hostdata *hostdata = shost_priv(instance);
 
@@ -534,7 +536,7 @@ static int __maybe_unused NCR5380_show_i
 #endif
 
 /**
- * NCR5380_init	-	initialise an NCR5380
+ * NCR5380_init - initialise an NCR5380
  * @instance: adapter to configure
  * @flags: control flags
  *
@@ -542,7 +544,7 @@ static int __maybe_unused NCR5380_show_i
  * 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.
+ * set correctly. I don't care about the irq and other fields.
  *
  * Returns 0 for success
  */
@@ -552,10 +554,9 @@ static int NCR5380_init(struct Scsi_Host
 	struct NCR5380_hostdata *hostdata = shost_priv(instance);
 	int i;
 
-	if(in_interrupt())
-		printk(KERN_ERR "NCR5380_init called with interrupts off!\n");
-
+	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;
@@ -580,8 +581,6 @@ static int NCR5380_init(struct Scsi_Host
 	if (!hostdata->work_q)
 		return -ENOMEM;
 
-	hostdata->host = instance;
-
 	prepare_info(instance);
 
 #ifndef REAL_DMA
@@ -592,6 +591,7 @@ static int NCR5380_init(struct Scsi_Host
 	NCR5380_write(MODE_REG, MR_BASE);
 	NCR5380_write(TARGET_COMMAND_REG, 0);
 	NCR5380_write(SELECT_ENABLE_REG, 0);
+
 	return 0;
 }
 
@@ -648,8 +648,10 @@ static int NCR5380_maybe_reset_bus(struc
 }
 
 /**
- * NCR5380_exit	-	remove an NCR5380
+ * 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)
@@ -714,7 +716,7 @@ static int NCR5380_queue_command(struct
 		cmd->scsi_done(cmd);
 		return 0;
 	}
-#endif				/* (NDEBUG & NDEBUG_NO_WRITE) */
+#endif /* (NDEBUG & NDEBUG_NO_WRITE) */
 
 	cmd->result = 0;
 
@@ -801,7 +803,7 @@ static void requeue_cmd(struct Scsi_Host
 }
 
 /**
- * NCR5380_main	-	NCR state machines
+ * 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
@@ -1067,7 +1069,9 @@ static struct scsi_cmnd *NCR5380_select(
 	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)) {
+	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);
@@ -1092,6 +1096,7 @@ static struct scsi_cmnd *NCR5380_select(
 		spin_lock_irq(&hostdata->lock);
 		goto out;
 	}
+
 	/*
 	 * Again, bus clear + bus settle time is 1.2us, however, this is
 	 * a minimum so we'll udelay ceil(1.2)
@@ -1144,7 +1149,7 @@ static struct scsi_cmnd *NCR5380_select(
 	 * 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 */
+	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));
@@ -1281,7 +1286,7 @@ out:
  * 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
+ * maximum number of bytes, 0 if all bytes are transferred or exit
  * is in same phase.
  *
  * Also, *phase, *count, *data are modified in place.
@@ -1295,7 +1300,10 @@ out:
  * 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) {
+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;
@@ -1306,7 +1314,7 @@ static int NCR5380_transfer_pio(struct S
 	 * REGISTER match the STATUS REGISTER
 	 */
 
-	 NCR5380_write(TARGET_COMMAND_REG, PHASE_SR_TO_TCR(p));
+	NCR5380_write(TARGET_COMMAND_REG, PHASE_SR_TO_TCR(p));
 
 	do {
 		/*
@@ -1325,6 +1333,7 @@ static int NCR5380_transfer_pio(struct S
 			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);
@@ -1462,12 +1471,14 @@ static int do_abort(struct Scsi_Host *in
 	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);
+		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;
@@ -1506,7 +1517,11 @@ timeout:
  */
 
 
-static int NCR5380_transfer_dma(struct Scsi_Host *instance, unsigned char *phase, int *count, unsigned char **data) {
+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;
 	register unsigned char *d = *data;
@@ -1517,8 +1532,6 @@ static int NCR5380_transfer_dma(struct S
 	unsigned char saved_data = 0, overrun = 0, residue;
 #endif
 
-	struct NCR5380_hostdata *hostdata = shost_priv(instance);
-
 	if ((tmp = (NCR5380_read(STATUS_REG) & PHASE_MASK)) != p) {
 		*phase = tmp;
 		return -1;
@@ -1748,7 +1761,8 @@ static int NCR5380_transfer_dma(struct S
  * to recover from an unexpected bus free condition.
  */
 
-static void NCR5380_information_transfer(struct Scsi_Host *instance) {
+static void NCR5380_information_transfer(struct Scsi_Host *instance)
+{
 	struct NCR5380_hostdata *hostdata = shost_priv(instance);
 	unsigned char msgout = NOP;
 	int sink = 0;
@@ -1775,11 +1789,13 @@ static void NCR5380_information_transfer
 				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);
+				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)
@@ -1805,6 +1821,7 @@ static void NCR5380_information_transfer
 					         cmd->SCp.this_residual,
 					         cmd->SCp.buffers_residual);
 				}
+
 				/*
 				 * The preferred transfer method is going to be
 				 * PSEUDO-DMA for systems that are strictly PIO,
@@ -1823,13 +1840,15 @@ static void NCR5380_information_transfer
 
 				if (transfersize) {
 					len = transfersize;
-					if (NCR5380_transfer_dma(instance, &phase, &len, (unsigned char **) &cmd->SCp.ptr)) {
+					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.
+						 * 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");
+							"switching to slow handshake\n");
 						cmd->device->borken = 1;
 						sink = 1;
 						do_abort(instance);
@@ -1905,25 +1924,24 @@ static void NCR5380_information_transfer
 						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);
+				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);
+					/*
+					 * 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);
-						return;
-					}
+					/* Enable reselect interrupts */
+					NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
+					return;
 					/*
 					 * The SCSI data pointer is *IMPLICITLY* saved on a disconnect
 					 * operation, in violation of the SCSI spec so we can safely
@@ -2013,15 +2031,17 @@ static void NCR5380_information_transfer
 						printk("\n");
 					} else if (tmp != EXTENDED_MESSAGE)
 						scmd_printk(KERN_INFO, cmd,
-							"rejecting unknown message %02x\n",tmp);
+						            "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]);
+						            "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) */
+				} /* switch (tmp) */
 				break;
 			case PHASE_MSGOUT:
 				len = 1;
@@ -2056,7 +2076,7 @@ static void NCR5380_information_transfer
 			default:
 				shost_printk(KERN_ERR, instance, "unknown phase\n");
 				NCR5380_dprint(NDEBUG_ANY, instance);
-			}	/* switch(phase) */
+			} /* switch(phase) */
 		} else {
 			spin_unlock_irq(&hostdata->lock);
 			NCR5380_poll_politely(instance, STATUS_REG, SR_REQ, SR_REQ, HZ);
@@ -2075,7 +2095,8 @@ static void NCR5380_information_transfer
  * Inputs : instance - this instance of the NCR5380.
  */
 
-static void NCR5380_reselect(struct Scsi_Host *instance) {
+static void NCR5380_reselect(struct Scsi_Host *instance)
+{
 	struct NCR5380_hostdata *hostdata = shost_priv(instance);
 	unsigned char target_mask;
 	unsigned char lun, phase;
@@ -2172,8 +2193,8 @@ static void NCR5380_reselect(struct Scsi
 		shost_printk(KERN_ERR, instance, "target bitmask 0x%02x lun %d not in disconnected queue.\n",
 		             target_mask, lun);
 		/*
-		 * Since we have an established nexus that we can't do anything with,
-		 * we must abort it.
+		 * Since we have an established nexus that we can't do anything
+		 * with, we must abort it.
 		 */
 		do_abort(instance);
 		return;

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

* [PATCH 70/71] atari_NCR5380: Merge changes from NCR5380.c
  2015-11-18  8:34 ` Finn Thain
@ 2015-11-18  8:36   ` Finn Thain
  -1 siblings, 0 replies; 268+ messages in thread
From: Finn Thain @ 2015-11-18  8:36 UTC (permalink / raw)
  To: James E.J. Bottomley, Michael Schmitz, linux-m68k, linux-scsi,
	linux-kernel

[-- Attachment #1: atari_NCR5380-merge-trivia-from-NCR5380 --]
[-- Type: text/plain, Size: 5998 bytes --]

In the past, atari_NCR5380.c was overlooked by those working on NCR5380.c
and this caused needless divergence. All of the changes in this patch were
taken from NCR5380.c.

This removes some unimportant discrepancies between the two core driver
forks so that 'diff' can be used to reveal the important ones, to
facilitate reunification.

Signed-off-by: Finn Thain <fthain@telegraphics.com.au>

---
 drivers/scsi/atari_NCR5380.c |  108 +++++++++++++++++++++++++------------------
 1 file changed, 64 insertions(+), 44 deletions(-)

Index: linux/drivers/scsi/atari_NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/atari_NCR5380.c	2015-11-18 19:34:38.000000000 +1100
+++ linux/drivers/scsi/atari_NCR5380.c	2015-11-18 19:34:46.000000000 +1100
@@ -454,22 +454,39 @@ 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"},
+	{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}
-}, 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"},
+},
+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"},
+	{MR_DMA_MODE, "MODE DMA"},
+	{MR_ARBITRATE, "MODE ARBITRATION"},
 	{0, NULL}
 };
 
@@ -513,8 +530,12 @@ 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_DATAOUT, "DATAOUT"},
+	{PHASE_DATAIN, "DATAIN"},
+	{PHASE_CMDOUT, "CMDOUT"},
+	{PHASE_STATIN, "STATIN"},
+	{PHASE_MSGOUT, "MSGOUT"},
+	{PHASE_MSGIN, "MSGIN"},
 	{PHASE_UNKNOWN, "UNKNOWN"}
 };
 
@@ -540,7 +561,6 @@ static void NCR5380_print_phase(struct S
 		shost_printk(KERN_DEBUG, instance, "phase %s\n", phases[i].name);
 	}
 }
-
 #endif
 
 /**
@@ -1501,9 +1521,9 @@ static int NCR5380_transfer_pio(struct S
 				unsigned char *phase, int *count,
 				unsigned char **data)
 {
-	register unsigned char p = *phase, tmp;
-	register int c = *count;
-	register unsigned char *d = *data;
+	unsigned char p = *phase, tmp;
+	int c = *count;
+	unsigned char *d = *data;
 
 	/*
 	 * The NCR5380 chip will only drive the SCSI bus when the
@@ -1570,17 +1590,17 @@ static int NCR5380_transfer_pio(struct S
 
 		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.
-		 */
+/*
+ * 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);
@@ -1645,7 +1665,7 @@ static void do_reset(struct Scsi_Host *i
 
 static int do_abort(struct Scsi_Host *instance)
 {
-	unsigned char tmp, *msgptr, phase;
+	unsigned char *msgptr, phase, tmp;
 	int len;
 	int rc;
 
@@ -2104,18 +2124,18 @@ static void NCR5380_information_transfer
 					NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
 					break;
 				case EXTENDED_MESSAGE:
-					/*
-					 * Extended messages are sent in the following format :
-					 * Byte
-					 * 0		EXTENDED_MESSAGE == 1
-					 * 1		length (includes one byte for code, doesn't
-					 * include first two bytes)
-					 * 2		code
-					 * 3..length+1	arguments
-					 *
-					 * Start the extended message buffer with the EXTENDED_MESSAGE
-					 * byte, since spi_print_msg() wants the whole thing.
-					 */
+/*
+ * Extended messages are sent in the following format :
+ * Byte
+ * 0            EXTENDED_MESSAGE == 1
+ * 1            length (includes one byte for code, doesn't
+ * include first two bytes)
+ * 2            code
+ * 3..length+1  arguments
+ *
+ * Start the extended 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);



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

* [PATCH 70/71] atari_NCR5380: Merge changes from NCR5380.c
@ 2015-11-18  8:36   ` Finn Thain
  0 siblings, 0 replies; 268+ messages in thread
From: Finn Thain @ 2015-11-18  8:36 UTC (permalink / raw)
  To: James E.J. Bottomley, Michael Schmitz, linux-m68k, linux-scsi,
	linux-kernel

[-- Attachment #1: atari_NCR5380-merge-trivia-from-NCR5380 --]
[-- Type: text/plain, Size: 5996 bytes --]

In the past, atari_NCR5380.c was overlooked by those working on NCR5380.c
and this caused needless divergence. All of the changes in this patch were
taken from NCR5380.c.

This removes some unimportant discrepancies between the two core driver
forks so that 'diff' can be used to reveal the important ones, to
facilitate reunification.

Signed-off-by: Finn Thain <fthain@telegraphics.com.au>

---
 drivers/scsi/atari_NCR5380.c |  108 +++++++++++++++++++++++++------------------
 1 file changed, 64 insertions(+), 44 deletions(-)

Index: linux/drivers/scsi/atari_NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/atari_NCR5380.c	2015-11-18 19:34:38.000000000 +1100
+++ linux/drivers/scsi/atari_NCR5380.c	2015-11-18 19:34:46.000000000 +1100
@@ -454,22 +454,39 @@ 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"},
+	{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}
-}, 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"},
+},
+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"},
+	{MR_DMA_MODE, "MODE DMA"},
+	{MR_ARBITRATE, "MODE ARBITRATION"},
 	{0, NULL}
 };
 
@@ -513,8 +530,12 @@ 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_DATAOUT, "DATAOUT"},
+	{PHASE_DATAIN, "DATAIN"},
+	{PHASE_CMDOUT, "CMDOUT"},
+	{PHASE_STATIN, "STATIN"},
+	{PHASE_MSGOUT, "MSGOUT"},
+	{PHASE_MSGIN, "MSGIN"},
 	{PHASE_UNKNOWN, "UNKNOWN"}
 };
 
@@ -540,7 +561,6 @@ static void NCR5380_print_phase(struct S
 		shost_printk(KERN_DEBUG, instance, "phase %s\n", phases[i].name);
 	}
 }
-
 #endif
 
 /**
@@ -1501,9 +1521,9 @@ static int NCR5380_transfer_pio(struct S
 				unsigned char *phase, int *count,
 				unsigned char **data)
 {
-	register unsigned char p = *phase, tmp;
-	register int c = *count;
-	register unsigned char *d = *data;
+	unsigned char p = *phase, tmp;
+	int c = *count;
+	unsigned char *d = *data;
 
 	/*
 	 * The NCR5380 chip will only drive the SCSI bus when the
@@ -1570,17 +1590,17 @@ static int NCR5380_transfer_pio(struct S
 
 		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.
-		 */
+/*
+ * 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);
@@ -1645,7 +1665,7 @@ static void do_reset(struct Scsi_Host *i
 
 static int do_abort(struct Scsi_Host *instance)
 {
-	unsigned char tmp, *msgptr, phase;
+	unsigned char *msgptr, phase, tmp;
 	int len;
 	int rc;
 
@@ -2104,18 +2124,18 @@ static void NCR5380_information_transfer
 					NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
 					break;
 				case EXTENDED_MESSAGE:
-					/*
-					 * Extended messages are sent in the following format :
-					 * Byte
-					 * 0		EXTENDED_MESSAGE == 1
-					 * 1		length (includes one byte for code, doesn't
-					 * include first two bytes)
-					 * 2		code
-					 * 3..length+1	arguments
-					 *
-					 * Start the extended message buffer with the EXTENDED_MESSAGE
-					 * byte, since spi_print_msg() wants the whole thing.
-					 */
+/*
+ * Extended messages are sent in the following format :
+ * Byte
+ * 0            EXTENDED_MESSAGE == 1
+ * 1            length (includes one byte for code, doesn't
+ * include first two bytes)
+ * 2            code
+ * 3..length+1  arguments
+ *
+ * Start the extended 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);

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

* [PATCH 71/71] ncr5380: Cleanup whitespace and parentheses
  2015-11-18  8:34 ` Finn Thain
@ 2015-11-18  8:36   ` Finn Thain
  -1 siblings, 0 replies; 268+ messages in thread
From: Finn Thain @ 2015-11-18  8:36 UTC (permalink / raw)
  To: James E.J. Bottomley, Michael Schmitz, linux-m68k, linux-scsi,
	linux-kernel

[-- Attachment #1: ncr5380-fix-whitespace-and-trivia --]
[-- Type: text/plain, Size: 7587 bytes --]

Signed-off-by: Finn Thain <fthain@telegraphics.com.au>

---
 drivers/scsi/NCR5380.c       |   30 +++++++++++++++++++-----------
 drivers/scsi/atari_NCR5380.c |   26 +++++++++++++-------------
 2 files changed, 32 insertions(+), 24 deletions(-)

Index: linux/drivers/scsi/NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/NCR5380.c	2015-11-18 19:34:43.000000000 +1100
+++ linux/drivers/scsi/NCR5380.c	2015-11-18 19:34:49.000000000 +1100
@@ -1126,7 +1126,7 @@ static struct scsi_cmnd *NCR5380_select(
 	 * the host and target ID's on the SCSI bus.
 	 */
 
-	NCR5380_write(OUTPUT_DATA_REG, (hostdata->id_mask | (1 << scmd_id(cmd))));
+	NCR5380_write(OUTPUT_DATA_REG, hostdata->id_mask | (1 << scmd_id(cmd)));
 
 	/*
 	 * Raise ATN while SEL is true before BSY goes false from arbitration,
@@ -1134,7 +1134,8 @@ static struct scsi_cmnd *NCR5380_select(
 	 * 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(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_BSY |
+	              ICR_ASSERT_DATA | ICR_ASSERT_ATN | ICR_ASSERT_SEL);
 	NCR5380_write(MODE_REG, MR_BASE);
 
 	/*
@@ -1152,7 +1153,8 @@ static struct scsi_cmnd *NCR5380_select(
 	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));
+	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
@@ -1262,7 +1264,7 @@ static struct scsi_cmnd *NCR5380_select(
 	/* XXX need to handle errors here */
 
 	hostdata->connected = cmd;
-	hostdata->busy[cmd->device->id] |= (1 << (cmd->device->lun & 0xFF));
+	hostdata->busy[cmd->device->id] |= 1 << cmd->device->lun;
 
 	initialize_SCp(cmd);
 
@@ -1353,11 +1355,14 @@ static int NCR5380_transfer_pio(struct S
 			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);
+				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_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);
+				NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE |
+				              ICR_ASSERT_DATA | ICR_ASSERT_ATN | ICR_ASSERT_ACK);
 			}
 		} else {
 			NCR5380_dprint(NDEBUG_PIO, instance);
@@ -1788,10 +1793,12 @@ static void NCR5380_information_transfer
 			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);
+				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);
+				NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE |
+				              ICR_ASSERT_ATN);
 				sink = 0;
 				continue;
 			}
@@ -1861,8 +1868,9 @@ static void NCR5380_information_transfer
 #endif				/* defined(PSEUDO_DMA) || defined(REAL_DMA_POLL) */
 				{
 					spin_unlock_irq(&hostdata->lock);
-					NCR5380_transfer_pio(instance, &phase, (int *) &cmd->SCp.this_residual, (unsigned char **)
-							     &cmd->SCp.ptr);
+					NCR5380_transfer_pio(instance, &phase,
+					                     (int *)&cmd->SCp.this_residual,
+					                     (unsigned char **)&cmd->SCp.ptr);
 					spin_lock_irq(&hostdata->lock);
 				}
 				break;
Index: linux/drivers/scsi/atari_NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/atari_NCR5380.c	2015-11-18 19:34:46.000000000 +1100
+++ linux/drivers/scsi/atari_NCR5380.c	2015-11-18 19:34:49.000000000 +1100
@@ -1327,7 +1327,7 @@ static struct scsi_cmnd *NCR5380_select(
 	 * the host and target ID's on the SCSI bus.
 	 */
 
-	NCR5380_write(OUTPUT_DATA_REG, (hostdata->id_mask | (1 << cmd->device->id)));
+	NCR5380_write(OUTPUT_DATA_REG, hostdata->id_mask | (1 << scmd_id(cmd)));
 
 	/*
 	 * Raise ATN while SEL is true before BSY goes false from arbitration,
@@ -1335,8 +1335,8 @@ static struct scsi_cmnd *NCR5380_select(
 	 * 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(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_BSY |
+	              ICR_ASSERT_DATA | ICR_ASSERT_ATN | ICR_ASSERT_SEL);
 	NCR5380_write(MODE_REG, MR_BASE);
 
 	/*
@@ -1354,8 +1354,8 @@ static struct scsi_cmnd *NCR5380_select(
 	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));
+	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
@@ -1475,7 +1475,7 @@ static struct scsi_cmnd *NCR5380_select(
 
 	hostdata->connected = cmd;
 #ifndef SUPPORT_TAGS
-	hostdata->busy[cmd->device->id] |= (1 << cmd->device->lun);
+	hostdata->busy[cmd->device->id] |= 1 << cmd->device->lun;
 #endif
 #ifdef SUN3_SCSI_VME
 	dregs->csr |= CSR_INTR;
@@ -1571,13 +1571,13 @@ static int NCR5380_transfer_pio(struct S
 				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);
+				              ICR_ASSERT_DATA | ICR_ASSERT_ACK);
 			} else {
 				NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE |
-					      ICR_ASSERT_DATA | ICR_ASSERT_ATN);
+				              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);
+				              ICR_ASSERT_DATA | ICR_ASSERT_ATN | ICR_ASSERT_ACK);
 			}
 		} else {
 			NCR5380_dprint(NDEBUG_PIO, instance);
@@ -1905,11 +1905,11 @@ static void NCR5380_information_transfer
 				NCR5380_write(TARGET_COMMAND_REG, PHASE_SR_TO_TCR(tmp));
 
 				NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_ATN |
-					      ICR_ASSERT_ACK);
+				              ICR_ASSERT_ACK);
 				while (NCR5380_read(STATUS_REG) & SR_REQ)
 					;
 				NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE |
-					      ICR_ASSERT_ATN);
+				              ICR_ASSERT_ATN);
 				sink = 0;
 				continue;
 			}
@@ -1998,8 +1998,8 @@ static void NCR5380_information_transfer
 				{
 					spin_unlock_irq(&hostdata->lock);
 					NCR5380_transfer_pio(instance, &phase,
-							     (int *)&cmd->SCp.this_residual,
-							     (unsigned char **)&cmd->SCp.ptr);
+					                     (int *)&cmd->SCp.this_residual,
+					                     (unsigned char **)&cmd->SCp.ptr);
 					spin_lock_irq(&hostdata->lock);
 				}
 #if defined(CONFIG_SUN3) && defined(REAL_DMA)



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

* [PATCH 71/71] ncr5380: Cleanup whitespace and parentheses
@ 2015-11-18  8:36   ` Finn Thain
  0 siblings, 0 replies; 268+ messages in thread
From: Finn Thain @ 2015-11-18  8:36 UTC (permalink / raw)
  To: James E.J. Bottomley, Michael Schmitz, linux-m68k, linux-scsi,
	linux-kernel

[-- Attachment #1: ncr5380-fix-whitespace-and-trivia --]
[-- Type: text/plain, Size: 7587 bytes --]

Signed-off-by: Finn Thain <fthain@telegraphics.com.au>

---
 drivers/scsi/NCR5380.c       |   30 +++++++++++++++++++-----------
 drivers/scsi/atari_NCR5380.c |   26 +++++++++++++-------------
 2 files changed, 32 insertions(+), 24 deletions(-)

Index: linux/drivers/scsi/NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/NCR5380.c	2015-11-18 19:34:43.000000000 +1100
+++ linux/drivers/scsi/NCR5380.c	2015-11-18 19:34:49.000000000 +1100
@@ -1126,7 +1126,7 @@ static struct scsi_cmnd *NCR5380_select(
 	 * the host and target ID's on the SCSI bus.
 	 */
 
-	NCR5380_write(OUTPUT_DATA_REG, (hostdata->id_mask | (1 << scmd_id(cmd))));
+	NCR5380_write(OUTPUT_DATA_REG, hostdata->id_mask | (1 << scmd_id(cmd)));
 
 	/*
 	 * Raise ATN while SEL is true before BSY goes false from arbitration,
@@ -1134,7 +1134,8 @@ static struct scsi_cmnd *NCR5380_select(
 	 * 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(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_BSY |
+	              ICR_ASSERT_DATA | ICR_ASSERT_ATN | ICR_ASSERT_SEL);
 	NCR5380_write(MODE_REG, MR_BASE);
 
 	/*
@@ -1152,7 +1153,8 @@ static struct scsi_cmnd *NCR5380_select(
 	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));
+	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
@@ -1262,7 +1264,7 @@ static struct scsi_cmnd *NCR5380_select(
 	/* XXX need to handle errors here */
 
 	hostdata->connected = cmd;
-	hostdata->busy[cmd->device->id] |= (1 << (cmd->device->lun & 0xFF));
+	hostdata->busy[cmd->device->id] |= 1 << cmd->device->lun;
 
 	initialize_SCp(cmd);
 
@@ -1353,11 +1355,14 @@ static int NCR5380_transfer_pio(struct S
 			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);
+				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_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);
+				NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE |
+				              ICR_ASSERT_DATA | ICR_ASSERT_ATN | ICR_ASSERT_ACK);
 			}
 		} else {
 			NCR5380_dprint(NDEBUG_PIO, instance);
@@ -1788,10 +1793,12 @@ static void NCR5380_information_transfer
 			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);
+				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);
+				NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE |
+				              ICR_ASSERT_ATN);
 				sink = 0;
 				continue;
 			}
@@ -1861,8 +1868,9 @@ static void NCR5380_information_transfer
 #endif				/* defined(PSEUDO_DMA) || defined(REAL_DMA_POLL) */
 				{
 					spin_unlock_irq(&hostdata->lock);
-					NCR5380_transfer_pio(instance, &phase, (int *) &cmd->SCp.this_residual, (unsigned char **)
-							     &cmd->SCp.ptr);
+					NCR5380_transfer_pio(instance, &phase,
+					                     (int *)&cmd->SCp.this_residual,
+					                     (unsigned char **)&cmd->SCp.ptr);
 					spin_lock_irq(&hostdata->lock);
 				}
 				break;
Index: linux/drivers/scsi/atari_NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/atari_NCR5380.c	2015-11-18 19:34:46.000000000 +1100
+++ linux/drivers/scsi/atari_NCR5380.c	2015-11-18 19:34:49.000000000 +1100
@@ -1327,7 +1327,7 @@ static struct scsi_cmnd *NCR5380_select(
 	 * the host and target ID's on the SCSI bus.
 	 */
 
-	NCR5380_write(OUTPUT_DATA_REG, (hostdata->id_mask | (1 << cmd->device->id)));
+	NCR5380_write(OUTPUT_DATA_REG, hostdata->id_mask | (1 << scmd_id(cmd)));
 
 	/*
 	 * Raise ATN while SEL is true before BSY goes false from arbitration,
@@ -1335,8 +1335,8 @@ static struct scsi_cmnd *NCR5380_select(
 	 * 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(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_BSY |
+	              ICR_ASSERT_DATA | ICR_ASSERT_ATN | ICR_ASSERT_SEL);
 	NCR5380_write(MODE_REG, MR_BASE);
 
 	/*
@@ -1354,8 +1354,8 @@ static struct scsi_cmnd *NCR5380_select(
 	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));
+	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
@@ -1475,7 +1475,7 @@ static struct scsi_cmnd *NCR5380_select(
 
 	hostdata->connected = cmd;
 #ifndef SUPPORT_TAGS
-	hostdata->busy[cmd->device->id] |= (1 << cmd->device->lun);
+	hostdata->busy[cmd->device->id] |= 1 << cmd->device->lun;
 #endif
 #ifdef SUN3_SCSI_VME
 	dregs->csr |= CSR_INTR;
@@ -1571,13 +1571,13 @@ static int NCR5380_transfer_pio(struct S
 				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);
+				              ICR_ASSERT_DATA | ICR_ASSERT_ACK);
 			} else {
 				NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE |
-					      ICR_ASSERT_DATA | ICR_ASSERT_ATN);
+				              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);
+				              ICR_ASSERT_DATA | ICR_ASSERT_ATN | ICR_ASSERT_ACK);
 			}
 		} else {
 			NCR5380_dprint(NDEBUG_PIO, instance);
@@ -1905,11 +1905,11 @@ static void NCR5380_information_transfer
 				NCR5380_write(TARGET_COMMAND_REG, PHASE_SR_TO_TCR(tmp));
 
 				NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_ATN |
-					      ICR_ASSERT_ACK);
+				              ICR_ASSERT_ACK);
 				while (NCR5380_read(STATUS_REG) & SR_REQ)
 					;
 				NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE |
-					      ICR_ASSERT_ATN);
+				              ICR_ASSERT_ATN);
 				sink = 0;
 				continue;
 			}
@@ -1998,8 +1998,8 @@ static void NCR5380_information_transfer
 				{
 					spin_unlock_irq(&hostdata->lock);
 					NCR5380_transfer_pio(instance, &phase,
-							     (int *)&cmd->SCp.this_residual,
-							     (unsigned char **)&cmd->SCp.ptr);
+					                     (int *)&cmd->SCp.this_residual,
+					                     (unsigned char **)&cmd->SCp.ptr);
 					spin_lock_irq(&hostdata->lock);
 				}
 #if defined(CONFIG_SUN3) && defined(REAL_DMA)



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

* Re: [PATCH 00/71] More fixes, cleanup and modernization for NCR5380 drivers
  2015-11-18  8:34 ` Finn Thain
                   ` (71 preceding siblings ...)
  (?)
@ 2015-11-18 11:35 ` Ondrej Zary
  2015-11-19  2:24   ` Finn Thain
  -1 siblings, 1 reply; 268+ messages in thread
From: Ondrej Zary @ 2015-11-18 11:35 UTC (permalink / raw)
  To: Finn Thain
  Cc: James E.J. Bottomley, Michael Schmitz, linux-m68k, linux-scsi,
	linux-kernel

On Wednesday 18 November 2015, Finn Thain wrote:
> Like my previous work on the NCR5380 drivers, this patch series has bug
> fixes, code cleanup and modernization. These drivers suffer from mistakes,
> poor style and neglect and this long series addresses the worst of it,
> covering all ten wrapper drivers and both of the core driver forks. The
> combined size of the drivers is reduced by about 750 LoC.
>
> This series continues to reduce divergence between the two core driver
> forks, often by copying a bug fix from one to the other. Most patches are
> larger for having to keep the two forks in sync. Making the same change to
> both is churn if one of them is to be removed but neither can be as yet.
> By the end of this series the diff between the two forks is minimal, so it
> becomes clear what caused the fork and what can be done about it.
>
> This patch series did benefit from scripts/checkpatch.pl but not too much.
> Decades ago, these drivers started out with 4-space tabs and if the 80
> column limit were to be strictly enforced now, it would require adding new
> functions and shortening identifiers. I would defer this sort of activity
> until after the fork has been resolved.
>
> I have compile-tested all patches to all NCR5380 drivers (x86, ARM, m68k)
> and regression tested mac_scsi and dmx3191d modules on suitable hardware.
> Testing the mac_scsi and dmx3191d modules provides only limited coverage.
> It would be good to see some testing of ISA cards and Sun 3 and Atari
> hardware too (I don't have any).

I have some NCR5380 ISA cards and can test them.

-- 
Ondrej Zary

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

* Re: [PATCH 00/71] More fixes, cleanup and modernization for NCR5380 drivers
  2015-11-18 11:35 ` [PATCH 00/71] More fixes, cleanup and modernization for NCR5380 drivers Ondrej Zary
@ 2015-11-19  2:24   ` Finn Thain
  2015-11-19  2:52     ` Michael Schmitz
                       ` (2 more replies)
  0 siblings, 3 replies; 268+ messages in thread
From: Finn Thain @ 2015-11-19  2:24 UTC (permalink / raw)
  To: Sam Creasey, Michael Schmitz, Ondrej Zary
  Cc: James E.J. Bottomley, linux-m68k, linux-scsi, linux-kernel


On Wed, 18 Nov 2015, Ondrej Zary wrote:

> On Wednesday 18 November 2015, Finn Thain wrote:
> 
> > Like my previous work on the NCR5380 drivers, this patch series has 
> > bug fixes, code cleanup and modernization. These drivers suffer from 
> > mistakes, poor style and neglect and this long series addresses the 
> > worst of it, covering all ten wrapper drivers and both of the core 
> > driver forks. The combined size of the drivers is reduced by about 750 
> > LoC.
> >
> > This series continues to reduce divergence between the two core driver 
> > forks, often by copying a bug fix from one to the other. Most patches 
> > are larger for having to keep the two forks in sync. Making the same 
> > change to both is churn if one of them is to be removed but neither 
> > can be as yet. By the end of this series the diff between the two 
> > forks is minimal, so it becomes clear what caused the fork and what 
> > can be done about it.
> >
> > This patch series did benefit from scripts/checkpatch.pl but not too 
> > much. Decades ago, these drivers started out with 4-space tabs and if 
> > the 80 column limit were to be strictly enforced now, it would require 
> > adding new functions and shortening identifiers. I would defer this 
> > sort of activity until after the fork has been resolved.
> >
> > I have compile-tested all patches to all NCR5380 drivers (x86, ARM, 
> > m68k) and regression tested mac_scsi and dmx3191d modules on suitable 
> > hardware. Testing the mac_scsi and dmx3191d modules provides only 
> > limited coverage. It would be good to see some testing of ISA cards 
> > and Sun 3 and Atari hardware too (I don't have any).
> 
> I have some NCR5380 ISA cards and can test them.
> 

Thanks Ondrej. I've no idea which ISA drivers are presently working in 
mainline. Finding regressions may be more difficult than usual ;-)

Michael, Sam: only atari_scsi and sun3_scsi implement DMA support, so some
testing of either driver would be helpful.

-- 

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

* Re: [PATCH 00/71] More fixes, cleanup and modernization for NCR5380 drivers
  2015-11-19  2:24   ` Finn Thain
@ 2015-11-19  2:52     ` Michael Schmitz
  2015-11-19  7:48     ` Ondrej Zary
  2015-11-19 22:50     ` Ondrej Zary
  2 siblings, 0 replies; 268+ messages in thread
From: Michael Schmitz @ 2015-11-19  2:52 UTC (permalink / raw)
  To: Finn Thain, Sam Creasey, Ondrej Zary
  Cc: James E.J. Bottomley, linux-m68k, linux-scsi, linux-kernel

Hi Finn,

>>>
>>> I have compile-tested all patches to all NCR5380 drivers (x86, ARM, 
>>> m68k) and regression tested mac_scsi and dmx3191d modules on suitable 
>>> hardware. Testing the mac_scsi and dmx3191d modules provides only 
>>> limited coverage. It would be good to see some testing of ISA cards 
>>> and Sun 3 and Atari hardware too (I don't have any).
>>
>> I have some NCR5380 ISA cards and can test them.
>>
> 
> Thanks Ondrej. I've no idea which ISA drivers are presently working in 
> mainline. Finding regressions may be more difficult than usual ;-)
> 
> Michael, Sam: only atari_scsi and sun3_scsi implement DMA support, so some
> testing of either driver would be helpful.

One way or another, I'll test this series or get someone to test a
kernel I built.

Cheers,
	
	Michael




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

* Re: [PATCH 10/71] atari_NCR5380: Remove RESET_BOOT, CONFIG_ATARI_SCSI_TOSHIBA_DELAY and CONFIG_ATARI_SCSI_RESET_BOOT
  2015-11-18  8:35   ` Finn Thain
  (?)
@ 2015-11-19  3:05   ` Michael Schmitz
  2015-11-19  4:05     ` Finn Thain
  -1 siblings, 1 reply; 268+ messages in thread
From: Michael Schmitz @ 2015-11-19  3:05 UTC (permalink / raw)
  To: Finn Thain, James E.J. Bottomley, linux-m68k, linux-scsi, linux-kernel

Hi Finn,

Am 18.11.2015 um 21:35 schrieb Finn Thain:

> The bus reset may raise an interrupt. That would be new behaviour for
> atari_scsi only when CONFIG_ATARI_SCSI_RESET_BOOT=n. The ST DMA interrupt
> is not assigned to atari_scsi at this stage, so
> CONFIG_ATARI_SCSI_RESET_BOOT=y may well be problematic already.

I can confirm that the bus reset at boot has never been problematic in
the past. It's been enabled in my kernels as long as I've used the
driver (must be getting close to 20 years now).

Cheers,


	Michael


> Regardless, do_reset() now raises and clears the interrupt within
> local_irq_save/restore which should avoid problems.
> 
> Signed-off-by: Finn Thain <fthain@telegraphics.com.au>
> 
> ---
>  drivers/scsi/Kconfig         |   17 -----------
>  drivers/scsi/NCR5380.c       |   17 +++++++++--
>  drivers/scsi/NCR5380.h       |    1 
>  drivers/scsi/atari_NCR5380.c |   22 +++++++++-----
>  drivers/scsi/atari_scsi.c    |   60 +++++----------------------------------
>  drivers/scsi/mac_scsi.c      |   65 ++++++-------------------------------------
>  drivers/scsi/sun3_scsi.c     |   47 -------------------------------
>  7 files changed, 51 insertions(+), 178 deletions(-)
> 
> Index: linux/drivers/scsi/Kconfig
> ===================================================================
> --- linux.orig/drivers/scsi/Kconfig	2015-11-18 19:25:56.000000000 +1100
> +++ linux/drivers/scsi/Kconfig	2015-11-18 19:33:15.000000000 +1100
> @@ -1624,23 +1624,6 @@ config ATARI_SCSI
>  	  ST-DMA, replacing ACSI).  It does NOT support other schemes, like
>  	  in the Hades (without DMA).
>  
> -config ATARI_SCSI_TOSHIBA_DELAY
> -	bool "Long delays for Toshiba CD-ROMs"
> -	depends on ATARI_SCSI
> -	help
> -	  This option increases the delay after a SCSI arbitration to
> -	  accommodate some flaky Toshiba CD-ROM drives. Say Y if you intend to
> -	  use a Toshiba CD-ROM drive; otherwise, the option is not needed and
> -	  would impact performance a bit, so say N.
> -
> -config ATARI_SCSI_RESET_BOOT
> -	bool "Reset SCSI-devices at boottime"
> -	depends on ATARI_SCSI
> -	help
> -	  Reset the devices on your Atari whenever it boots.  This makes the
> -	  boot process fractionally longer but may assist recovery from errors
> -	  that leave the devices with SCSI operations partway completed.
> -
>  config MAC_SCSI
>  	tristate "Macintosh NCR5380 SCSI"
>  	depends on MAC && SCSI=y
> Index: linux/drivers/scsi/atari_NCR5380.c
> ===================================================================
> --- linux.orig/drivers/scsi/atari_NCR5380.c	2015-11-18 19:33:13.000000000 +1100
> +++ linux/drivers/scsi/atari_NCR5380.c	2015-11-18 19:33:15.000000000 +1100
> @@ -674,13 +674,14 @@ static void prepare_info(struct Scsi_Hos
>  	         "base 0x%lx, irq %d, "
>  	         "can_queue %d, cmd_per_lun %d, "
>  	         "sg_tablesize %d, this_id %d, "
> -	         "flags { %s}, "
> +	         "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
> @@ -860,6 +861,7 @@ static int __init NCR5380_init(struct Sc
>  
>  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) {
> @@ -878,6 +880,14 @@ static int NCR5380_maybe_reset_bus(struc
>  		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");
> @@ -1493,12 +1503,10 @@ static int NCR5380_select(struct Scsi_Ho
>  	 * a minimum so we'll udelay ceil(1.2)
>  	 */
>  
> -#ifdef CONFIG_ATARI_SCSI_TOSHIBA_DELAY
> -	/* ++roman: But some targets (see above :-) seem to need a bit more... */
> -	udelay(15);
> -#else
> -	udelay(2);
> -#endif
> +	if (hostdata->flags & FLAG_TOSHIBA_DELAY)
> +		udelay(15);
> +	else
> +		udelay(2);
>  
>  	if (hostdata->connected) {
>  		NCR5380_write(MODE_REG, MR_BASE);
> Index: linux/drivers/scsi/atari_scsi.c
> ===================================================================
> --- linux.orig/drivers/scsi/atari_scsi.c	2015-11-18 19:32:58.000000000 +1100
> +++ linux/drivers/scsi/atari_scsi.c	2015-11-18 19:33:15.000000000 +1100
> @@ -164,15 +164,6 @@ static inline unsigned long SCSI_DMA_GET
>  #define HOSTDATA_DMALEN		(((struct NCR5380_hostdata *) \
>  				(atari_scsi_host->hostdata))->dma_len)
>  
> -/* Time (in jiffies) to wait after a reset; the SCSI standard calls for 250ms,
> - * we usually do 0.5s to be on the safe side. But Toshiba CD-ROMs once more
> - * need ten times the standard value... */
> -#ifndef CONFIG_ATARI_SCSI_TOSHIBA_DELAY
> -#define	AFTER_RESET_DELAY	(HZ/2)
> -#else
> -#define	AFTER_RESET_DELAY	(5*HZ/2)
> -#endif
> -
>  #ifdef REAL_DMA
>  static void atari_scsi_fetch_restbytes(void);
>  #endif
> @@ -208,12 +199,12 @@ 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);
> +static int setup_toshiba_delay = -1;
> +module_param(setup_toshiba_delay, int, 0);
>  
>  
>  #if defined(REAL_DMA)
> @@ -488,7 +479,7 @@ static int __init atari_scsi_setup(char
>  	 * Defaults depend on TT or Falcon, determined at run time.
>  	 * Negative values mean don't change.
>  	 */
> -	int ints[6];
> +	int ints[8];
>  
>  	get_options(str, ARRAY_SIZE(ints), ints);
>  
> @@ -504,10 +495,11 @@ static int __init atari_scsi_setup(char
>  		setup_sg_tablesize = ints[3];
>  	if (ints[0] >= 4)
>  		setup_hostid = ints[4];
> -#ifdef SUPPORT_TAGS
>  	if (ints[0] >= 5)
>  		setup_use_tagged_queuing = ints[5];
> -#endif
> +	/* ints[6] (use_pdma) is ignored */
> +	if (ints[0] >= 7)
> +		setup_toshiba_delay = ints[7];
>  
>  	return 1;
>  }
> @@ -516,38 +508,6 @@ __setup("atascsi=", atari_scsi_setup);
>  #endif /* !MODULE */
>  
>  
> -#ifdef CONFIG_ATARI_SCSI_RESET_BOOT
> -static void __init atari_scsi_reset_boot(void)
> -{
> -	unsigned long end;
> -
> -	/*
> -	 * Do a SCSI reset to clean up the bus during initialization. No messing
> -	 * with the queues, interrupts, or locks necessary here.
> -	 */
> -
> -	printk("Atari SCSI: resetting the SCSI bus...");
> -
> -	/* get in phase */
> -	NCR5380_write(TARGET_COMMAND_REG,
> -		      PHASE_SR_TO_TCR(NCR5380_read(STATUS_REG)));
> -
> -	/* assert RST */
> -	NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_RST);
> -	/* The min. reset hold time is 25us, so 40us should be enough */
> -	udelay(50);
> -	/* reset RST and interrupt */
> -	NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
> -	NCR5380_read(RESET_PARITY_INTERRUPT_REG);
> -
> -	end = jiffies + AFTER_RESET_DELAY;
> -	while (time_before(jiffies, end))
> -		barrier();
> -
> -	printk(" done\n");
> -}
> -#endif
> -
>  #if defined(REAL_DMA)
>  
>  static unsigned long atari_scsi_dma_setup(struct Scsi_Host *instance,
> @@ -917,17 +877,13 @@ static int __init atari_scsi_probe(struc
>  	}
>  	atari_scsi_host = instance;
>  
> -#ifdef CONFIG_ATARI_SCSI_RESET_BOOT
> -	atari_scsi_reset_boot();
> -#endif
> -
>  	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;
>  
>  	NCR5380_init(instance, host_flags);
>  
> @@ -975,6 +931,8 @@ static int __init atari_scsi_probe(struc
>  #endif
>  	}
>  
> +	NCR5380_maybe_reset_bus(instance);
> +
>  	error = scsi_add_host(instance, NULL);
>  	if (error)
>  		goto fail_host;
> Index: linux/drivers/scsi/mac_scsi.c
> ===================================================================
> --- linux.orig/drivers/scsi/mac_scsi.c	2015-11-18 19:33:05.000000000 +1100
> +++ linux/drivers/scsi/mac_scsi.c	2015-11-18 19:33:15.000000000 +1100
> @@ -49,8 +49,6 @@
>  
>  #include "NCR5380.h"
>  
> -#define RESET_BOOT
> -
>  static int setup_can_queue = -1;
>  module_param(setup_can_queue, int, 0);
>  static int setup_cmd_per_lun = -1;
> @@ -63,17 +61,8 @@ 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);
> -
> -/* Time (in jiffies) to wait after a reset; the SCSI standard calls for 250ms,
> - * we usually do 0.5s to be on the safe side. But Toshiba CD-ROMs once more
> - * need ten times the standard value... */
> -#define TOSHIBA_DELAY
> -
> -#ifdef TOSHIBA_DELAY
> -#define	AFTER_RESET_DELAY	(5*HZ/2)
> -#else
> -#define	AFTER_RESET_DELAY	(HZ/2)
> -#endif
> +static int setup_toshiba_delay = -1;
> +module_param(setup_toshiba_delay, int, 0);
>  
>  /*
>   * NCR 5380 register access functions
> @@ -92,12 +81,12 @@ static inline void macscsi_write(struct
>  #ifndef MODULE
>  static int __init mac_scsi_setup(char *str)
>  {
> -	int ints[7];
> +	int ints[8];
>  
>  	(void)get_options(str, ARRAY_SIZE(ints), ints);
>  
> -	if (ints[0] < 1 || ints[0] > 6) {
> -		pr_err("Usage: mac5380=<can_queue>[,<cmd_per_lun>[,<sg_tablesize>[,<hostid>[,<use_tags>[,<use_pdma>]]]]]\n");
> +	if (ints[0] < 1) {
> +		pr_err("Usage: mac5380=<can_queue>[,<cmd_per_lun>[,<sg_tablesize>[,<hostid>[,<use_tags>[,<use_pdma>[,toshiba_delay]]]]]]\n");
>  		return 0;
>  	}
>  	if (ints[0] >= 1)
> @@ -112,47 +101,14 @@ static int __init mac_scsi_setup(char *s
>  		setup_use_tagged_queuing = ints[5];
>  	if (ints[0] >= 6)
>  		setup_use_pdma = ints[6];
> +	if (ints[0] >= 7)
> +		setup_toshiba_delay = ints[7];
>  	return 1;
>  }
>  
>  __setup("mac5380=", mac_scsi_setup);
>  #endif /* !MODULE */
>  
> -#ifdef RESET_BOOT
> -/*
> - * Our 'bus reset on boot' function
> - */
> -
> -static void mac_scsi_reset_boot(struct Scsi_Host *instance)
> -{
> -	unsigned long end;
> -
> -	/*
> -	 * Do a SCSI reset to clean up the bus during initialization. No messing
> -	 * with the queues, interrupts, or locks necessary here.
> -	 */
> -
> -	printk(KERN_INFO "Macintosh SCSI: resetting the SCSI bus..." );
> -
> -	/* get in phase */
> -	NCR5380_write( TARGET_COMMAND_REG,
> -		      PHASE_SR_TO_TCR( NCR5380_read(STATUS_REG) ));
> -
> -	/* assert RST */
> -	NCR5380_write( INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_RST );
> -	/* The min. reset hold time is 25us, so 40us should be enough */
> -	udelay( 50 );
> -	/* reset RST and interrupt */
> -	NCR5380_write( INITIATOR_COMMAND_REG, ICR_BASE );
> -	NCR5380_read( RESET_PARITY_INTERRUPT_REG );
> -
> -	for( end = jiffies + AFTER_RESET_DELAY; time_before(jiffies, end); )
> -		barrier();
> -
> -	printk(KERN_INFO " done\n" );
> -}
> -#endif
> -
>  #ifdef PSEUDO_DMA
>  /* 
>     Pseudo-DMA: (Ove Edlund)
> @@ -421,13 +377,10 @@ static int __init mac_scsi_probe(struct
>  	} else
>  		host_flags |= FLAG_NO_PSEUDO_DMA;
>  
> -#ifdef RESET_BOOT
> -	mac_scsi_reset_boot(instance);
> -#endif
> -
>  #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;
>  
>  	NCR5380_init(instance, host_flags);
>  
> @@ -438,6 +391,8 @@ static int __init mac_scsi_probe(struct
>  			goto fail_irq;
>  	}
>  
> +	NCR5380_maybe_reset_bus(instance);
> +
>  	error = scsi_add_host(instance, NULL);
>  	if (error)
>  		goto fail_host;
> Index: linux/drivers/scsi/sun3_scsi.c
> ===================================================================
> --- linux.orig/drivers/scsi/sun3_scsi.c	2015-11-18 19:32:59.000000000 +1100
> +++ linux/drivers/scsi/sun3_scsi.c	2015-11-18 19:33:15.000000000 +1100
> @@ -86,10 +86,6 @@ module_param(setup_use_tagged_queuing, i
>  static int setup_hostid = -1;
>  module_param(setup_hostid, int, 0);
>  
> -/* #define RESET_BOOT */
> -
> -#define	AFTER_RESET_DELAY	(HZ/2)
> -
>  /* ms to wait after hitting dma regs */
>  #define SUN3_DMA_DELAY 10
>  
> @@ -144,45 +140,6 @@ static inline void sun3_udc_write(unsign
>  }
>  #endif
>  
> -#ifdef RESET_BOOT
> -static void sun3_scsi_reset_boot(struct Scsi_Host *instance)
> -{
> -	unsigned long end;
> -	
> -	/*
> -	 * Do a SCSI reset to clean up the bus during initialization. No
> -	 * messing with the queues, interrupts, or locks necessary here.
> -	 */
> -
> -	printk( "Sun3 SCSI: resetting the SCSI bus..." );
> -
> -	/* switch off SCSI IRQ - catch an interrupt without IRQ bit set else */
> -//       	sun3_disable_irq( IRQ_SUN3_SCSI );
> -
> -	/* get in phase */
> -	NCR5380_write( TARGET_COMMAND_REG,
> -		      PHASE_SR_TO_TCR( NCR5380_read(STATUS_REG) ));
> -
> -	/* assert RST */
> -	NCR5380_write( INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_RST );
> -
> -	/* The min. reset hold time is 25us, so 40us should be enough */
> -	udelay( 50 );
> -
> -	/* reset RST and interrupt */
> -	NCR5380_write( INITIATOR_COMMAND_REG, ICR_BASE );
> -	NCR5380_read( RESET_PARITY_INTERRUPT_REG );
> -
> -	for( end = jiffies + AFTER_RESET_DELAY; time_before(jiffies, end); )
> -		barrier();
> -
> -	/* switch on SCSI IRQ again */
> -//       	sun3_enable_irq( IRQ_SUN3_SCSI );
> -
> -	printk( " done\n" );
> -}
> -#endif
> -
>  // safe bits for the CSR
>  #define CSR_GOOD 0x060f
>  
> @@ -631,9 +588,7 @@ static int __init sun3_scsi_probe(struct
>  	dregs->ivect = VME_DATA24 | (instance->irq & 0xff);
>  #endif
>  
> -#ifdef RESET_BOOT
> -	sun3_scsi_reset_boot(instance);
> -#endif
> +	NCR5380_maybe_reset_bus(instance);
>  
>  	error = scsi_add_host(instance, NULL);
>  	if (error)
> Index: linux/drivers/scsi/NCR5380.h
> ===================================================================
> --- linux.orig/drivers/scsi/NCR5380.h	2015-11-18 19:33:10.000000000 +1100
> +++ linux/drivers/scsi/NCR5380.h	2015-11-18 19:33:15.000000000 +1100
> @@ -243,6 +243,7 @@
>  #define FLAG_DTC3181E			16	/* DTC3181E */
>  #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 {
> Index: linux/drivers/scsi/NCR5380.c
> ===================================================================
> --- linux.orig/drivers/scsi/NCR5380.c	2015-11-18 19:33:13.000000000 +1100
> +++ linux/drivers/scsi/NCR5380.c	2015-11-18 19:33:15.000000000 +1100
> @@ -618,7 +618,7 @@ static void prepare_info(struct Scsi_Hos
>  	         "base 0x%lx, irq %d, "
>  	         "can_queue %d, cmd_per_lun %d, "
>  	         "sg_tablesize %d, this_id %d, "
> -	         "flags { %s%s%s}, "
> +	         "flags { %s%s%s%s}, "
>  #if defined(USLEEP_POLL) && defined(USLEEP_WAITLONG)
>  		 "USLEEP_POLL %lu, USLEEP_WAITLONG %lu, "
>  #endif
> @@ -630,6 +630,7 @@ static void prepare_info(struct Scsi_Hos
>  	         hostdata->flags & FLAG_NCR53C400     ? "NCR53C400 "     : "",
>  	         hostdata->flags & FLAG_DTC3181E      ? "DTC3181E "      : "",
>  	         hostdata->flags & FLAG_NO_PSEUDO_DMA ? "NO_PSEUDO_DMA " : "",
> +	         hostdata->flags & FLAG_TOSHIBA_DELAY ? "TOSHIBA_DELAY "  : "",
>  #if defined(USLEEP_POLL) && defined(USLEEP_WAITLONG)
>  	         USLEEP_POLL, USLEEP_WAITLONG,
>  #endif
> @@ -831,6 +832,7 @@ static int NCR5380_init(struct Scsi_Host
>  
>  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) {
> @@ -849,6 +851,14 @@ static int NCR5380_maybe_reset_bus(struc
>  		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");
> @@ -1253,7 +1263,10 @@ static int NCR5380_select(struct Scsi_Ho
>  	 * a minimum so we'll udelay ceil(1.2)
>  	 */
>  
> -	udelay(2);
> +	if (hostdata->flags & FLAG_TOSHIBA_DELAY)
> +		udelay(15);
> +	else
> +		udelay(2);
>  
>  	dprintk(NDEBUG_ARBITRATION, "scsi%d : won arbitration\n", instance->host_no);
>  
> 
> 

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

* Re: [PATCH 10/71] atari_NCR5380: Remove RESET_BOOT, CONFIG_ATARI_SCSI_TOSHIBA_DELAY and CONFIG_ATARI_SCSI_RESET_BOOT
  2015-11-19  3:05   ` Michael Schmitz
@ 2015-11-19  4:05     ` Finn Thain
  2015-11-19  4:43       ` Michael Schmitz
  0 siblings, 1 reply; 268+ messages in thread
From: Finn Thain @ 2015-11-19  4:05 UTC (permalink / raw)
  To: Michael Schmitz
  Cc: James E.J. Bottomley, linux-m68k, linux-scsi, linux-kernel

w
On Thu, 19 Nov 2015, Michael Schmitz wrote:

> Hi Finn,
> 
> Am 18.11.2015 um 21:35 schrieb Finn Thain:
> 
> > The bus reset may raise an interrupt. That would be new behaviour for 
> > atari_scsi only when CONFIG_ATARI_SCSI_RESET_BOOT=n. The ST DMA 
> > interrupt is not assigned to atari_scsi at this stage, so 
> > CONFIG_ATARI_SCSI_RESET_BOOT=y may well be problematic already.
> 
> I can confirm that the bus reset at boot has never been problematic in 
> the past. It's been enabled in my kernels as long as I've used the 
> driver (must be getting close to 20 years now).

That's good to know. I'm not sure why it was configurable in the first 
place (long delays?). The new algorithm (the one I copied from NCR5380.c) 
does not allow the user to prevent a possible scsi bus reset at driver 
init time. The scsi bus reset only takes place if the driver discovers 
that the bus was already wedged when it started. (It proved useful when I 
was introducing faults for EH testing, BTW.)

-- 

> 
> Cheers,
> 
> 
> 	Michael
> 
> 
> > Regardless, do_reset() now raises and clears the interrupt within
> > local_irq_save/restore which should avoid problems.
> > 
> > Signed-off-by: Finn Thain <fthain@telegraphics.com.au>
> > 
> > ---
> >  drivers/scsi/Kconfig         |   17 -----------
> >  drivers/scsi/NCR5380.c       |   17 +++++++++--
> >  drivers/scsi/NCR5380.h       |    1 
> >  drivers/scsi/atari_NCR5380.c |   22 +++++++++-----
> >  drivers/scsi/atari_scsi.c    |   60 +++++----------------------------------
> >  drivers/scsi/mac_scsi.c      |   65 ++++++-------------------------------------
> >  drivers/scsi/sun3_scsi.c     |   47 -------------------------------
> >  7 files changed, 51 insertions(+), 178 deletions(-)
> > 
> > Index: linux/drivers/scsi/Kconfig
> > ===================================================================
> > --- linux.orig/drivers/scsi/Kconfig	2015-11-18 19:25:56.000000000 +1100
> > +++ linux/drivers/scsi/Kconfig	2015-11-18 19:33:15.000000000 +1100
> > @@ -1624,23 +1624,6 @@ config ATARI_SCSI
> >  	  ST-DMA, replacing ACSI).  It does NOT support other schemes, like
> >  	  in the Hades (without DMA).
> >  
> > -config ATARI_SCSI_TOSHIBA_DELAY
> > -	bool "Long delays for Toshiba CD-ROMs"
> > -	depends on ATARI_SCSI
> > -	help
> > -	  This option increases the delay after a SCSI arbitration to
> > -	  accommodate some flaky Toshiba CD-ROM drives. Say Y if you intend to
> > -	  use a Toshiba CD-ROM drive; otherwise, the option is not needed and
> > -	  would impact performance a bit, so say N.
> > -
> > -config ATARI_SCSI_RESET_BOOT
> > -	bool "Reset SCSI-devices at boottime"
> > -	depends on ATARI_SCSI
> > -	help
> > -	  Reset the devices on your Atari whenever it boots.  This makes the
> > -	  boot process fractionally longer but may assist recovery from errors
> > -	  that leave the devices with SCSI operations partway completed.
> > -
> >  config MAC_SCSI
> >  	tristate "Macintosh NCR5380 SCSI"
> >  	depends on MAC && SCSI=y
> > Index: linux/drivers/scsi/atari_NCR5380.c
> > ===================================================================
> > --- linux.orig/drivers/scsi/atari_NCR5380.c	2015-11-18 19:33:13.000000000 +1100
> > +++ linux/drivers/scsi/atari_NCR5380.c	2015-11-18 19:33:15.000000000 +1100
> > @@ -674,13 +674,14 @@ static void prepare_info(struct Scsi_Hos
> >  	         "base 0x%lx, irq %d, "
> >  	         "can_queue %d, cmd_per_lun %d, "
> >  	         "sg_tablesize %d, this_id %d, "
> > -	         "flags { %s}, "
> > +	         "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
> > @@ -860,6 +861,7 @@ static int __init NCR5380_init(struct Sc
> >  
> >  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) {
> > @@ -878,6 +880,14 @@ static int NCR5380_maybe_reset_bus(struc
> >  		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");
> > @@ -1493,12 +1503,10 @@ static int NCR5380_select(struct Scsi_Ho
> >  	 * a minimum so we'll udelay ceil(1.2)
> >  	 */
> >  
> > -#ifdef CONFIG_ATARI_SCSI_TOSHIBA_DELAY
> > -	/* ++roman: But some targets (see above :-) seem to need a bit more... */
> > -	udelay(15);
> > -#else
> > -	udelay(2);
> > -#endif
> > +	if (hostdata->flags & FLAG_TOSHIBA_DELAY)
> > +		udelay(15);
> > +	else
> > +		udelay(2);
> >  
> >  	if (hostdata->connected) {
> >  		NCR5380_write(MODE_REG, MR_BASE);
> > Index: linux/drivers/scsi/atari_scsi.c
> > ===================================================================
> > --- linux.orig/drivers/scsi/atari_scsi.c	2015-11-18 19:32:58.000000000 +1100
> > +++ linux/drivers/scsi/atari_scsi.c	2015-11-18 19:33:15.000000000 +1100
> > @@ -164,15 +164,6 @@ static inline unsigned long SCSI_DMA_GET
> >  #define HOSTDATA_DMALEN		(((struct NCR5380_hostdata *) \
> >  				(atari_scsi_host->hostdata))->dma_len)
> >  
> > -/* Time (in jiffies) to wait after a reset; the SCSI standard calls for 250ms,
> > - * we usually do 0.5s to be on the safe side. But Toshiba CD-ROMs once more
> > - * need ten times the standard value... */
> > -#ifndef CONFIG_ATARI_SCSI_TOSHIBA_DELAY
> > -#define	AFTER_RESET_DELAY	(HZ/2)
> > -#else
> > -#define	AFTER_RESET_DELAY	(5*HZ/2)
> > -#endif
> > -
> >  #ifdef REAL_DMA
> >  static void atari_scsi_fetch_restbytes(void);
> >  #endif
> > @@ -208,12 +199,12 @@ 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);
> > +static int setup_toshiba_delay = -1;
> > +module_param(setup_toshiba_delay, int, 0);
> >  
> >  
> >  #if defined(REAL_DMA)
> > @@ -488,7 +479,7 @@ static int __init atari_scsi_setup(char
> >  	 * Defaults depend on TT or Falcon, determined at run time.
> >  	 * Negative values mean don't change.
> >  	 */
> > -	int ints[6];
> > +	int ints[8];
> >  
> >  	get_options(str, ARRAY_SIZE(ints), ints);
> >  
> > @@ -504,10 +495,11 @@ static int __init atari_scsi_setup(char
> >  		setup_sg_tablesize = ints[3];
> >  	if (ints[0] >= 4)
> >  		setup_hostid = ints[4];
> > -#ifdef SUPPORT_TAGS
> >  	if (ints[0] >= 5)
> >  		setup_use_tagged_queuing = ints[5];
> > -#endif
> > +	/* ints[6] (use_pdma) is ignored */
> > +	if (ints[0] >= 7)
> > +		setup_toshiba_delay = ints[7];
> >  
> >  	return 1;
> >  }
> > @@ -516,38 +508,6 @@ __setup("atascsi=", atari_scsi_setup);
> >  #endif /* !MODULE */
> >  
> >  
> > -#ifdef CONFIG_ATARI_SCSI_RESET_BOOT
> > -static void __init atari_scsi_reset_boot(void)
> > -{
> > -	unsigned long end;
> > -
> > -	/*
> > -	 * Do a SCSI reset to clean up the bus during initialization. No messing
> > -	 * with the queues, interrupts, or locks necessary here.
> > -	 */
> > -
> > -	printk("Atari SCSI: resetting the SCSI bus...");
> > -
> > -	/* get in phase */
> > -	NCR5380_write(TARGET_COMMAND_REG,
> > -		      PHASE_SR_TO_TCR(NCR5380_read(STATUS_REG)));
> > -
> > -	/* assert RST */
> > -	NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_RST);
> > -	/* The min. reset hold time is 25us, so 40us should be enough */
> > -	udelay(50);
> > -	/* reset RST and interrupt */
> > -	NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
> > -	NCR5380_read(RESET_PARITY_INTERRUPT_REG);
> > -
> > -	end = jiffies + AFTER_RESET_DELAY;
> > -	while (time_before(jiffies, end))
> > -		barrier();
> > -
> > -	printk(" done\n");
> > -}
> > -#endif
> > -
> >  #if defined(REAL_DMA)
> >  
> >  static unsigned long atari_scsi_dma_setup(struct Scsi_Host *instance,
> > @@ -917,17 +877,13 @@ static int __init atari_scsi_probe(struc
> >  	}
> >  	atari_scsi_host = instance;
> >  
> > -#ifdef CONFIG_ATARI_SCSI_RESET_BOOT
> > -	atari_scsi_reset_boot();
> > -#endif
> > -
> >  	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;
> >  
> >  	NCR5380_init(instance, host_flags);
> >  
> > @@ -975,6 +931,8 @@ static int __init atari_scsi_probe(struc
> >  #endif
> >  	}
> >  
> > +	NCR5380_maybe_reset_bus(instance);
> > +
> >  	error = scsi_add_host(instance, NULL);
> >  	if (error)
> >  		goto fail_host;
> > Index: linux/drivers/scsi/mac_scsi.c
> > ===================================================================
> > --- linux.orig/drivers/scsi/mac_scsi.c	2015-11-18 19:33:05.000000000 +1100
> > +++ linux/drivers/scsi/mac_scsi.c	2015-11-18 19:33:15.000000000 +1100
> > @@ -49,8 +49,6 @@
> >  
> >  #include "NCR5380.h"
> >  
> > -#define RESET_BOOT
> > -
> >  static int setup_can_queue = -1;
> >  module_param(setup_can_queue, int, 0);
> >  static int setup_cmd_per_lun = -1;
> > @@ -63,17 +61,8 @@ 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);
> > -
> > -/* Time (in jiffies) to wait after a reset; the SCSI standard calls for 250ms,
> > - * we usually do 0.5s to be on the safe side. But Toshiba CD-ROMs once more
> > - * need ten times the standard value... */
> > -#define TOSHIBA_DELAY
> > -
> > -#ifdef TOSHIBA_DELAY
> > -#define	AFTER_RESET_DELAY	(5*HZ/2)
> > -#else
> > -#define	AFTER_RESET_DELAY	(HZ/2)
> > -#endif
> > +static int setup_toshiba_delay = -1;
> > +module_param(setup_toshiba_delay, int, 0);
> >  
> >  /*
> >   * NCR 5380 register access functions
> > @@ -92,12 +81,12 @@ static inline void macscsi_write(struct
> >  #ifndef MODULE
> >  static int __init mac_scsi_setup(char *str)
> >  {
> > -	int ints[7];
> > +	int ints[8];
> >  
> >  	(void)get_options(str, ARRAY_SIZE(ints), ints);
> >  
> > -	if (ints[0] < 1 || ints[0] > 6) {
> > -		pr_err("Usage: mac5380=<can_queue>[,<cmd_per_lun>[,<sg_tablesize>[,<hostid>[,<use_tags>[,<use_pdma>]]]]]\n");
> > +	if (ints[0] < 1) {
> > +		pr_err("Usage: mac5380=<can_queue>[,<cmd_per_lun>[,<sg_tablesize>[,<hostid>[,<use_tags>[,<use_pdma>[,toshiba_delay]]]]]]\n");
> >  		return 0;
> >  	}
> >  	if (ints[0] >= 1)
> > @@ -112,47 +101,14 @@ static int __init mac_scsi_setup(char *s
> >  		setup_use_tagged_queuing = ints[5];
> >  	if (ints[0] >= 6)
> >  		setup_use_pdma = ints[6];
> > +	if (ints[0] >= 7)
> > +		setup_toshiba_delay = ints[7];
> >  	return 1;
> >  }
> >  
> >  __setup("mac5380=", mac_scsi_setup);
> >  #endif /* !MODULE */
> >  
> > -#ifdef RESET_BOOT
> > -/*
> > - * Our 'bus reset on boot' function
> > - */
> > -
> > -static void mac_scsi_reset_boot(struct Scsi_Host *instance)
> > -{
> > -	unsigned long end;
> > -
> > -	/*
> > -	 * Do a SCSI reset to clean up the bus during initialization. No messing
> > -	 * with the queues, interrupts, or locks necessary here.
> > -	 */
> > -
> > -	printk(KERN_INFO "Macintosh SCSI: resetting the SCSI bus..." );
> > -
> > -	/* get in phase */
> > -	NCR5380_write( TARGET_COMMAND_REG,
> > -		      PHASE_SR_TO_TCR( NCR5380_read(STATUS_REG) ));
> > -
> > -	/* assert RST */
> > -	NCR5380_write( INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_RST );
> > -	/* The min. reset hold time is 25us, so 40us should be enough */
> > -	udelay( 50 );
> > -	/* reset RST and interrupt */
> > -	NCR5380_write( INITIATOR_COMMAND_REG, ICR_BASE );
> > -	NCR5380_read( RESET_PARITY_INTERRUPT_REG );
> > -
> > -	for( end = jiffies + AFTER_RESET_DELAY; time_before(jiffies, end); )
> > -		barrier();
> > -
> > -	printk(KERN_INFO " done\n" );
> > -}
> > -#endif
> > -
> >  #ifdef PSEUDO_DMA
> >  /* 
> >     Pseudo-DMA: (Ove Edlund)
> > @@ -421,13 +377,10 @@ static int __init mac_scsi_probe(struct
> >  	} else
> >  		host_flags |= FLAG_NO_PSEUDO_DMA;
> >  
> > -#ifdef RESET_BOOT
> > -	mac_scsi_reset_boot(instance);
> > -#endif
> > -
> >  #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;
> >  
> >  	NCR5380_init(instance, host_flags);
> >  
> > @@ -438,6 +391,8 @@ static int __init mac_scsi_probe(struct
> >  			goto fail_irq;
> >  	}
> >  
> > +	NCR5380_maybe_reset_bus(instance);
> > +
> >  	error = scsi_add_host(instance, NULL);
> >  	if (error)
> >  		goto fail_host;
> > Index: linux/drivers/scsi/sun3_scsi.c
> > ===================================================================
> > --- linux.orig/drivers/scsi/sun3_scsi.c	2015-11-18 19:32:59.000000000 +1100
> > +++ linux/drivers/scsi/sun3_scsi.c	2015-11-18 19:33:15.000000000 +1100
> > @@ -86,10 +86,6 @@ module_param(setup_use_tagged_queuing, i
> >  static int setup_hostid = -1;
> >  module_param(setup_hostid, int, 0);
> >  
> > -/* #define RESET_BOOT */
> > -
> > -#define	AFTER_RESET_DELAY	(HZ/2)
> > -
> >  /* ms to wait after hitting dma regs */
> >  #define SUN3_DMA_DELAY 10
> >  
> > @@ -144,45 +140,6 @@ static inline void sun3_udc_write(unsign
> >  }
> >  #endif
> >  
> > -#ifdef RESET_BOOT
> > -static void sun3_scsi_reset_boot(struct Scsi_Host *instance)
> > -{
> > -	unsigned long end;
> > -	
> > -	/*
> > -	 * Do a SCSI reset to clean up the bus during initialization. No
> > -	 * messing with the queues, interrupts, or locks necessary here.
> > -	 */
> > -
> > -	printk( "Sun3 SCSI: resetting the SCSI bus..." );
> > -
> > -	/* switch off SCSI IRQ - catch an interrupt without IRQ bit set else */
> > -//       	sun3_disable_irq( IRQ_SUN3_SCSI );
> > -
> > -	/* get in phase */
> > -	NCR5380_write( TARGET_COMMAND_REG,
> > -		      PHASE_SR_TO_TCR( NCR5380_read(STATUS_REG) ));
> > -
> > -	/* assert RST */
> > -	NCR5380_write( INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_RST );
> > -
> > -	/* The min. reset hold time is 25us, so 40us should be enough */
> > -	udelay( 50 );
> > -
> > -	/* reset RST and interrupt */
> > -	NCR5380_write( INITIATOR_COMMAND_REG, ICR_BASE );
> > -	NCR5380_read( RESET_PARITY_INTERRUPT_REG );
> > -
> > -	for( end = jiffies + AFTER_RESET_DELAY; time_before(jiffies, end); )
> > -		barrier();
> > -
> > -	/* switch on SCSI IRQ again */
> > -//       	sun3_enable_irq( IRQ_SUN3_SCSI );
> > -
> > -	printk( " done\n" );
> > -}
> > -#endif
> > -
> >  // safe bits for the CSR
> >  #define CSR_GOOD 0x060f
> >  
> > @@ -631,9 +588,7 @@ static int __init sun3_scsi_probe(struct
> >  	dregs->ivect = VME_DATA24 | (instance->irq & 0xff);
> >  #endif
> >  
> > -#ifdef RESET_BOOT
> > -	sun3_scsi_reset_boot(instance);
> > -#endif
> > +	NCR5380_maybe_reset_bus(instance);
> >  
> >  	error = scsi_add_host(instance, NULL);
> >  	if (error)
> > Index: linux/drivers/scsi/NCR5380.h
> > ===================================================================
> > --- linux.orig/drivers/scsi/NCR5380.h	2015-11-18 19:33:10.000000000 +1100
> > +++ linux/drivers/scsi/NCR5380.h	2015-11-18 19:33:15.000000000 +1100
> > @@ -243,6 +243,7 @@
> >  #define FLAG_DTC3181E			16	/* DTC3181E */
> >  #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 {
> > Index: linux/drivers/scsi/NCR5380.c
> > ===================================================================
> > --- linux.orig/drivers/scsi/NCR5380.c	2015-11-18 19:33:13.000000000 +1100
> > +++ linux/drivers/scsi/NCR5380.c	2015-11-18 19:33:15.000000000 +1100
> > @@ -618,7 +618,7 @@ static void prepare_info(struct Scsi_Hos
> >  	         "base 0x%lx, irq %d, "
> >  	         "can_queue %d, cmd_per_lun %d, "
> >  	         "sg_tablesize %d, this_id %d, "
> > -	         "flags { %s%s%s}, "
> > +	         "flags { %s%s%s%s}, "
> >  #if defined(USLEEP_POLL) && defined(USLEEP_WAITLONG)
> >  		 "USLEEP_POLL %lu, USLEEP_WAITLONG %lu, "
> >  #endif
> > @@ -630,6 +630,7 @@ static void prepare_info(struct Scsi_Hos
> >  	         hostdata->flags & FLAG_NCR53C400     ? "NCR53C400 "     : "",
> >  	         hostdata->flags & FLAG_DTC3181E      ? "DTC3181E "      : "",
> >  	         hostdata->flags & FLAG_NO_PSEUDO_DMA ? "NO_PSEUDO_DMA " : "",
> > +	         hostdata->flags & FLAG_TOSHIBA_DELAY ? "TOSHIBA_DELAY "  : "",
> >  #if defined(USLEEP_POLL) && defined(USLEEP_WAITLONG)
> >  	         USLEEP_POLL, USLEEP_WAITLONG,
> >  #endif
> > @@ -831,6 +832,7 @@ static int NCR5380_init(struct Scsi_Host
> >  
> >  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) {
> > @@ -849,6 +851,14 @@ static int NCR5380_maybe_reset_bus(struc
> >  		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");
> > @@ -1253,7 +1263,10 @@ static int NCR5380_select(struct Scsi_Ho
> >  	 * a minimum so we'll udelay ceil(1.2)
> >  	 */
> >  
> > -	udelay(2);
> > +	if (hostdata->flags & FLAG_TOSHIBA_DELAY)
> > +		udelay(15);
> > +	else
> > +		udelay(2);
> >  
> >  	dprintk(NDEBUG_ARBITRATION, "scsi%d : won arbitration\n", instance->host_no);
> >  
> > 
> > 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-m68k" 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] 268+ messages in thread

* Re: [PATCH 10/71] atari_NCR5380: Remove RESET_BOOT, CONFIG_ATARI_SCSI_TOSHIBA_DELAY and CONFIG_ATARI_SCSI_RESET_BOOT
  2015-11-19  4:05     ` Finn Thain
@ 2015-11-19  4:43       ` Michael Schmitz
  0 siblings, 0 replies; 268+ messages in thread
From: Michael Schmitz @ 2015-11-19  4:43 UTC (permalink / raw)
  To: Finn Thain; +Cc: James E.J. Bottomley, linux-m68k, linux-scsi, linux-kernel

Hi Finn,

Am 19.11.2015 um 17:05 schrieb Finn Thain:
> w
> On Thu, 19 Nov 2015, Michael Schmitz wrote:
> 
>> Hi Finn,
>>
>> Am 18.11.2015 um 21:35 schrieb Finn Thain:
>>
>>> The bus reset may raise an interrupt. That would be new behaviour for 
>>> atari_scsi only when CONFIG_ATARI_SCSI_RESET_BOOT=n. The ST DMA 
>>> interrupt is not assigned to atari_scsi at this stage, so 
>>> CONFIG_ATARI_SCSI_RESET_BOOT=y may well be problematic already.
>>
>> I can confirm that the bus reset at boot has never been problematic in 
>> the past. It's been enabled in my kernels as long as I've used the 
>> driver (must be getting close to 20 years now).
> 
> That's good to know. I'm not sure why it was configurable in the first 
> place (long delays?). The new algorithm (the one I copied from NCR5380.c) 

The longer delays (and possibly a reset at boot) were only necessary for
certain CD-ROM drives. I don't think I have ever seen such a device, and
it's a bit unlikely any of these still survive. Reset at boot before
proper driver init can probably go away now.

> does not allow the user to prevent a possible scsi bus reset at driver 
> init time. The scsi bus reset only takes place if the driver discovers 
> that the bus was already wedged when it started. (It proved useful when I 
> was introducing faults for EH testing, BTW.)

Much saner approach, I'm sure. Don't forget the driver was written
before sophisticated error handling came along. Reset at boot and keep
your fingers crossed was the strategy in these days.

Cheers,

	Michael


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

* Re: [PATCH 01/71] atari_scsi: Fix SCSI host ID setting
  2015-11-18  8:34   ` Finn Thain
  (?)
@ 2015-11-19  7:37   ` Hannes Reinecke
  -1 siblings, 0 replies; 268+ messages in thread
From: Hannes Reinecke @ 2015-11-19  7:37 UTC (permalink / raw)
  To: Finn Thain, James E.J. Bottomley, Michael Schmitz, linux-m68k,
	linux-scsi, linux-kernel

On 11/18/2015 09:34 AM, Finn Thain wrote:
> The NVRAM location of this byte is 16, as documented in
> http://toshyp.atari.org/en/004009.html
>
> This was confirmed by Michael Schmitz, by setting the SCSI host ID
> under EmuTOS and then checking the value in /proc/driver/nvram and
> /dev/nvram under Linux.
>
> Signed-off-by: Finn Thain <fthain@telegraphics.com.au>
>
Reviewed-by: Hannes Reinecke <hare@suse.com>

Cheers,

Hannes
-- 
Dr. Hannes Reinecke		               zSeries & Storage
hare@suse.de			               +49 911 74053 688
SUSE LINUX GmbH, Maxfeldstr. 5, 90409 Nürnberg
GF: F. Imendörffer, J. Smithard, J. Guild, D. Upmanyu, G. Norton
HRB 21284 (AG Nürnberg)


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

* Re: [PATCH 02/71] ncr5380: Remove redundant static variable initializers
  2015-11-18  8:34   ` Finn Thain
  (?)
@ 2015-11-19  7:37   ` Hannes Reinecke
  -1 siblings, 0 replies; 268+ messages in thread
From: Hannes Reinecke @ 2015-11-19  7:37 UTC (permalink / raw)
  To: Finn Thain, James E.J. Bottomley, Michael Schmitz, linux-m68k,
	linux-scsi, linux-kernel

On 11/18/2015 09:34 AM, Finn Thain wrote:
> Signed-off-by: Finn Thain <fthain@telegraphics.com.au>
>
> ---
>   drivers/scsi/NCR5380.c   |    2 +-
>   drivers/scsi/dtc.c       |    4 ++--
>   drivers/scsi/g_NCR5380.c |    4 ++--
>   drivers/scsi/pas16.c     |   10 +++++-----
>   drivers/scsi/sun3_scsi.c |    8 ++++----
>   drivers/scsi/t128.c      |    4 ++--
>   6 files changed, 16 insertions(+), 16 deletions(-)
>
Reviewed-by: Hannes Reinecke <hare@suse.com>

Cheers,

Hannes
-- 
Dr. Hannes Reinecke		               zSeries & Storage
hare@suse.de			               +49 911 74053 688
SUSE LINUX GmbH, Maxfeldstr. 5, 90409 Nürnberg
GF: F. Imendörffer, J. Smithard, J. Guild, D. Upmanyu, G. Norton
HRB 21284 (AG Nürnberg)


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

* Re: [PATCH 03/71] ncr5380: Eliminate PDEBUG*, TDEBUG* and DTCDEBUG* macros
  2015-11-18  8:34   ` Finn Thain
  (?)
@ 2015-11-19  7:38   ` Hannes Reinecke
  -1 siblings, 0 replies; 268+ messages in thread
From: Hannes Reinecke @ 2015-11-19  7:38 UTC (permalink / raw)
  To: Finn Thain, James E.J. Bottomley, Michael Schmitz, linux-m68k,
	linux-scsi, linux-kernel

On 11/18/2015 09:34 AM, Finn Thain wrote:
> Replace {P,T,DTC}DEBUG_INIT with NDEBUG_INIT. Remove dead debugging
> code, including code that's conditional upon *DEBUG_TRANSFER.
>
> Signed-off-by: Finn Thain <fthain@telegraphics.com.au>
>
> ---
>   drivers/scsi/dtc.c   |   18 ++++++------------
>   drivers/scsi/dtc.h   |   27 ---------------------------
>   drivers/scsi/pas16.c |   21 +++++++--------------
>   drivers/scsi/pas16.h |   16 ----------------
>   drivers/scsi/t128.c  |   18 ++++++------------
>   drivers/scsi/t128.h  |   16 ----------------
>   6 files changed, 19 insertions(+), 97 deletions(-)
>
Reviewed-by: Hannes Reinecke <hare@suse.com>

Cheers,

Hannes
-- 
Dr. Hannes Reinecke		               zSeries & Storage
hare@suse.de			               +49 911 74053 688
SUSE LINUX GmbH, Maxfeldstr. 5, 90409 Nürnberg
GF: F. Imendörffer, J. Smithard, J. Guild, D. Upmanyu, G. Norton
HRB 21284 (AG Nürnberg)


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

* Re: [PATCH 04/71] ncr5380: Remove more pointless macros
  2015-11-18  8:34   ` Finn Thain
  (?)
@ 2015-11-19  7:38   ` Hannes Reinecke
  -1 siblings, 0 replies; 268+ messages in thread
From: Hannes Reinecke @ 2015-11-19  7:38 UTC (permalink / raw)
  To: Finn Thain, James E.J. Bottomley, Michael Schmitz, linux-m68k,
	linux-scsi, linux-kernel

On 11/18/2015 09:34 AM, Finn Thain wrote:
> ASM macro is never defined. rtrc in pas16.c is not used.
> NCR5380_map_config, do_NCR5380_intr, do_t128_intr and do_pas16_intr
> are unused. NCR_NOT_SET harms readability. Remove them.
>
> Signed-off-by: Finn Thain <fthain@telegraphics.com.au>
>
> ---
>   drivers/scsi/NCR5380.h   |    3 ---
>   drivers/scsi/g_NCR5380.c |   29 ++++++++++++++---------------
>   drivers/scsi/g_NCR5380.h |    5 -----
>   drivers/scsi/pas16.c     |   16 ----------------
>   drivers/scsi/pas16.h     |    5 -----
>   drivers/scsi/t128.h      |    4 ----
>   6 files changed, 14 insertions(+), 48 deletions(-)
>
Reviewed-by: Hannes Reinecke <hare@suse.com>

Cheers,

Hannes
-- 
Dr. Hannes Reinecke		               zSeries & Storage
hare@suse.de			               +49 911 74053 688
SUSE LINUX GmbH, Maxfeldstr. 5, 90409 Nürnberg
GF: F. Imendörffer, J. Smithard, J. Guild, D. Upmanyu, G. Norton
HRB 21284 (AG Nürnberg)


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

* Re: [PATCH 05/71] ncr5380: Remove NCR5380_local_declare and NCR5380_setup macros
  2015-11-18  8:35   ` Finn Thain
@ 2015-11-19  7:41     ` Hannes Reinecke
  -1 siblings, 0 replies; 268+ messages in thread
From: Hannes Reinecke @ 2015-11-19  7:41 UTC (permalink / raw)
  To: Finn Thain, James E.J. Bottomley, Michael Schmitz, linux-m68k,
	linux-scsi, linux-kernel, Russell King, linux-arm-kernel

On 11/18/2015 09:35 AM, Finn Thain wrote:
> The NCR5380_local_declare and NCR5380_setup macros exist to define and
> initialize a particular local variable, to provide the address of the
> chip registers needed for the driver's implementation of its
> NCR5380_read/write register access macros.
>
> In cumana_1 and macscsi, these macros generate pointless code like this,
> 	struct Scsi_Host *_instance;
> 	_instance = instance;
>
> In pas16, the use of NCR5380_read/write in pas16_hw_detect() requires that
> the io_port local variable has been defined and initialized, but the
> NCR5380_local_declare and NCR5380_setup macros can't be used for that
> purpose because the Scsi_Host struct has not yet been instantiated.
>
> Moreover, these macros were removed from atari_NCR5380.c long ago and
> now they constitute yet another discrepancy between the two core driver
> forks.
>
> Remove these "optimizations".
>
> Signed-off-by: Finn Thain <fthain@telegraphics.com.au>
>
> ---
Reviewed-by: Hannes Reinecke <hare@suse.com>

Cheers,

Hannes
-- 
Dr. Hannes Reinecke		               zSeries & Storage
hare@suse.de			               +49 911 74053 688
SUSE LINUX GmbH, Maxfeldstr. 5, 90409 Nürnberg
GF: F. Imendörffer, J. Smithard, J. Guild, D. Upmanyu, G. Norton
HRB 21284 (AG Nürnberg)


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

* [PATCH 05/71] ncr5380: Remove NCR5380_local_declare and NCR5380_setup macros
@ 2015-11-19  7:41     ` Hannes Reinecke
  0 siblings, 0 replies; 268+ messages in thread
From: Hannes Reinecke @ 2015-11-19  7:41 UTC (permalink / raw)
  To: linux-arm-kernel

On 11/18/2015 09:35 AM, Finn Thain wrote:
> The NCR5380_local_declare and NCR5380_setup macros exist to define and
> initialize a particular local variable, to provide the address of the
> chip registers needed for the driver's implementation of its
> NCR5380_read/write register access macros.
>
> In cumana_1 and macscsi, these macros generate pointless code like this,
> 	struct Scsi_Host *_instance;
> 	_instance = instance;
>
> In pas16, the use of NCR5380_read/write in pas16_hw_detect() requires that
> the io_port local variable has been defined and initialized, but the
> NCR5380_local_declare and NCR5380_setup macros can't be used for that
> purpose because the Scsi_Host struct has not yet been instantiated.
>
> Moreover, these macros were removed from atari_NCR5380.c long ago and
> now they constitute yet another discrepancy between the two core driver
> forks.
>
> Remove these "optimizations".
>
> Signed-off-by: Finn Thain <fthain@telegraphics.com.au>
>
> ---
Reviewed-by: Hannes Reinecke <hare@suse.com>

Cheers,

Hannes
-- 
Dr. Hannes Reinecke		               zSeries & Storage
hare at suse.de			               +49 911 74053 688
SUSE LINUX GmbH, Maxfeldstr. 5, 90409 N?rnberg
GF: F. Imend?rffer, J. Smithard, J. Guild, D. Upmanyu, G. Norton
HRB 21284 (AG N?rnberg)

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

* Re: [PATCH 06/71] ncr5380: Remove NCR5380_instance_name macro
  2015-11-18  8:35   ` Finn Thain
  (?)
@ 2015-11-19  7:41   ` Hannes Reinecke
  -1 siblings, 0 replies; 268+ messages in thread
From: Hannes Reinecke @ 2015-11-19  7:41 UTC (permalink / raw)
  To: Finn Thain, James E.J. Bottomley, Michael Schmitz, linux-m68k,
	linux-scsi, linux-kernel

On 11/18/2015 09:35 AM, Finn Thain wrote:
> This macro makes the code cryptic. Remove it.
>
> Signed-off-by: Finn Thain <fthain@telegraphics.com.au>
>
> ---
>   drivers/scsi/NCR5380.c   |    2 +-
>   drivers/scsi/g_NCR5380.c |    7 ++++---
>   drivers/scsi/g_NCR5380.h |    2 --
>   3 files changed, 5 insertions(+), 6 deletions(-)
>
Reviewed-by: Hannes Reinecke <hare@suse.com>

Cheers,

Hannes
-- 
Dr. Hannes Reinecke		               zSeries & Storage
hare@suse.de			               +49 911 74053 688
SUSE LINUX GmbH, Maxfeldstr. 5, 90409 Nürnberg
GF: F. Imendörffer, J. Smithard, J. Guild, D. Upmanyu, G. Norton
HRB 21284 (AG Nürnberg)


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

* Re: [PATCH 00/71] More fixes, cleanup and modernization for NCR5380 drivers
  2015-11-19  2:24   ` Finn Thain
  2015-11-19  2:52     ` Michael Schmitz
@ 2015-11-19  7:48     ` Ondrej Zary
  2015-11-19 22:50     ` Ondrej Zary
  2 siblings, 0 replies; 268+ messages in thread
From: Ondrej Zary @ 2015-11-19  7:48 UTC (permalink / raw)
  To: Finn Thain
  Cc: Sam Creasey, Michael Schmitz, James E.J. Bottomley, linux-m68k,
	linux-scsi, linux-kernel

On Thursday 19 November 2015, Finn Thain wrote:
> On Wed, 18 Nov 2015, Ondrej Zary wrote:
> > On Wednesday 18 November 2015, Finn Thain wrote:
> > > Like my previous work on the NCR5380 drivers, this patch series has
> > > bug fixes, code cleanup and modernization. These drivers suffer from
> > > mistakes, poor style and neglect and this long series addresses the
> > > worst of it, covering all ten wrapper drivers and both of the core
> > > driver forks. The combined size of the drivers is reduced by about 750
> > > LoC.
> > >
> > > This series continues to reduce divergence between the two core driver
> > > forks, often by copying a bug fix from one to the other. Most patches
> > > are larger for having to keep the two forks in sync. Making the same
> > > change to both is churn if one of them is to be removed but neither
> > > can be as yet. By the end of this series the diff between the two
> > > forks is minimal, so it becomes clear what caused the fork and what
> > > can be done about it.
> > >
> > > This patch series did benefit from scripts/checkpatch.pl but not too
> > > much. Decades ago, these drivers started out with 4-space tabs and if
> > > the 80 column limit were to be strictly enforced now, it would require
> > > adding new functions and shortening identifiers. I would defer this
> > > sort of activity until after the fork has been resolved.
> > >
> > > I have compile-tested all patches to all NCR5380 drivers (x86, ARM,
> > > m68k) and regression tested mac_scsi and dmx3191d modules on suitable
> > > hardware. Testing the mac_scsi and dmx3191d modules provides only
> > > limited coverage. It would be good to see some testing of ISA cards
> > > and Sun 3 and Atari hardware too (I don't have any).
> >
> > I have some NCR5380 ISA cards and can test them.
>
> Thanks Ondrej. I've no idea which ISA drivers are presently working in
> mainline. Finding regressions may be more difficult than usual ;-)

I remember that at least one of them never worked in Linux - HP C2502 card 
with 53C400A chip with no jumpers (magic-numbers-based configuration).

The memory-mapped Canon FG2-5202 (53C400) did not work properly either.

At least DTCT-436P used to work.

-- 
Ondrej Zary

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

* Re: [PATCH 07/71] ncr5380: Split NCR5380_init() into two functions
  2015-11-18  8:35   ` Finn Thain
@ 2015-11-19 13:30     ` Hannes Reinecke
  -1 siblings, 0 replies; 268+ messages in thread
From: Hannes Reinecke @ 2015-11-19 13:30 UTC (permalink / raw)
  To: Finn Thain, James E.J. Bottomley, Michael Schmitz, linux-m68k,
	linux-scsi, linux-kernel, Russell King, linux-arm-kernel

On 11/18/2015 09:35 AM, Finn Thain wrote:
> This patch splits the NCR5380_init() function into two parts, similar
> to the scheme used with atari_NCR5380.c. This avoids two problems.
> 
> Firstly, NCR5380_init() may perform a bus reset, which would cause the
> chip to assert IRQ. The chip is unable to mask its bus reset interrupt.
> Drivers can't call request_irq() before calling NCR5380_init(), because
> initialization must happen before the interrupt handler executes. If
> driver initialization causes an interrupt it may be problematic on some
> platforms. To avoid that, first move the bus reset code into
> NCR5380_maybe_reset_bus().
> 
> Secondly, NCR5380_init() contains some board-specific interrupt setup code
> for the NCR53C400 that does not belong in the core driver. In moving this
> code, better not re-order interrupt initialization and bus reset. Again,
> the solution is to move the bus reset code into NCR5380_maybe_reset_bus().
> 
> Signed-off-by: Finn Thain <fthain@telegraphics.com.au>
> 
Reviewed-by: Hannes Reinecke <hare@suse.com>

Cheers,

Hannes
-- 
Dr. Hannes Reinecke		               zSeries & Storage
hare@suse.de			               +49 911 74053 688
SUSE LINUX GmbH, Maxfeldstr. 5, 90409 Nürnberg
GF: F. Imendörffer, J. Smithard, J. Guild, D. Upmanyu, G. Norton
HRB 21284 (AG Nürnberg)

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

* [PATCH 07/71] ncr5380: Split NCR5380_init() into two functions
@ 2015-11-19 13:30     ` Hannes Reinecke
  0 siblings, 0 replies; 268+ messages in thread
From: Hannes Reinecke @ 2015-11-19 13:30 UTC (permalink / raw)
  To: linux-arm-kernel

On 11/18/2015 09:35 AM, Finn Thain wrote:
> This patch splits the NCR5380_init() function into two parts, similar
> to the scheme used with atari_NCR5380.c. This avoids two problems.
> 
> Firstly, NCR5380_init() may perform a bus reset, which would cause the
> chip to assert IRQ. The chip is unable to mask its bus reset interrupt.
> Drivers can't call request_irq() before calling NCR5380_init(), because
> initialization must happen before the interrupt handler executes. If
> driver initialization causes an interrupt it may be problematic on some
> platforms. To avoid that, first move the bus reset code into
> NCR5380_maybe_reset_bus().
> 
> Secondly, NCR5380_init() contains some board-specific interrupt setup code
> for the NCR53C400 that does not belong in the core driver. In moving this
> code, better not re-order interrupt initialization and bus reset. Again,
> the solution is to move the bus reset code into NCR5380_maybe_reset_bus().
> 
> Signed-off-by: Finn Thain <fthain@telegraphics.com.au>
> 
Reviewed-by: Hannes Reinecke <hare@suse.com>

Cheers,

Hannes
-- 
Dr. Hannes Reinecke		               zSeries & Storage
hare at suse.de			               +49 911 74053 688
SUSE LINUX GmbH, Maxfeldstr. 5, 90409 N?rnberg
GF: F. Imend?rffer, J. Smithard, J. Guild, D. Upmanyu, G. Norton
HRB 21284 (AG N?rnberg)

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

* Re: [PATCH 08/71] ncr5380: Move NCR53C400-specific code
  2015-11-18  8:35   ` Finn Thain
@ 2015-11-19 13:31     ` Hannes Reinecke
  -1 siblings, 0 replies; 268+ messages in thread
From: Hannes Reinecke @ 2015-11-19 13:31 UTC (permalink / raw)
  To: Finn Thain, James E.J. Bottomley, Michael Schmitz, linux-m68k,
	linux-scsi, linux-kernel

On 11/18/2015 09:35 AM, Finn Thain wrote:
> Move board-specific code like this,
> 	NCR5380_write(C400_CONTROL_STATUS_REG, CSR_BASE);
> from the core driver to the board driver. Eliminate the NCR53C400 macro
> from the core driver. Removal of all macros like this one will be
> necessary in order to have one core driver that can support all kinds of
> boards.
> 
> Signed-off-by: Finn Thain <fthain@telegraphics.com.au>
> 
> ---
>  drivers/scsi/NCR5380.c   |   18 ------------------
>  drivers/scsi/g_NCR5380.c |   23 ++++++++++++++++++-----
>  drivers/scsi/g_NCR5380.h |    6 ++----
>  3 files changed, 20 insertions(+), 27 deletions(-)
> 
Reviewed-by: Hannes Reinecke <hare@suse.com>

Cheers,

Hannes
-- 
Dr. Hannes Reinecke		               zSeries & Storage
hare@suse.de			               +49 911 74053 688
SUSE LINUX GmbH, Maxfeldstr. 5, 90409 Nürnberg
GF: F. Imendörffer, J. Smithard, J. Guild, D. Upmanyu, G. Norton
HRB 21284 (AG Nürnberg)

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

* Re: [PATCH 08/71] ncr5380: Move NCR53C400-specific code
@ 2015-11-19 13:31     ` Hannes Reinecke
  0 siblings, 0 replies; 268+ messages in thread
From: Hannes Reinecke @ 2015-11-19 13:31 UTC (permalink / raw)
  To: Finn Thain, James E.J. Bottomley, Michael Schmitz, linux-m68k,
	linux-scsi, linux-kernel

On 11/18/2015 09:35 AM, Finn Thain wrote:
> Move board-specific code like this,
> 	NCR5380_write(C400_CONTROL_STATUS_REG, CSR_BASE);
> from the core driver to the board driver. Eliminate the NCR53C400 macro
> from the core driver. Removal of all macros like this one will be
> necessary in order to have one core driver that can support all kinds of
> boards.
> 
> Signed-off-by: Finn Thain <fthain@telegraphics.com.au>
> 
> ---
>  drivers/scsi/NCR5380.c   |   18 ------------------
>  drivers/scsi/g_NCR5380.c |   23 ++++++++++++++++++-----
>  drivers/scsi/g_NCR5380.h |    6 ++----
>  3 files changed, 20 insertions(+), 27 deletions(-)
> 
Reviewed-by: Hannes Reinecke <hare@suse.com>

Cheers,

Hannes
-- 
Dr. Hannes Reinecke		               zSeries & Storage
hare@suse.de			               +49 911 74053 688
SUSE LINUX GmbH, Maxfeldstr. 5, 90409 Nürnberg
GF: F. Imendörffer, J. Smithard, J. Guild, D. Upmanyu, G. Norton
HRB 21284 (AG Nürnberg)
--
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] 268+ messages in thread

* Re: [PATCH 09/71] atari_NCR5380: Reset bus on driver initialization if required
  2015-11-18  8:35   ` Finn Thain
  (?)
@ 2015-11-19 13:38   ` Hannes Reinecke
  -1 siblings, 0 replies; 268+ messages in thread
From: Hannes Reinecke @ 2015-11-19 13:38 UTC (permalink / raw)
  To: Finn Thain, James E.J. Bottomley, Michael Schmitz, linux-m68k,
	linux-scsi, linux-kernel

On 11/18/2015 09:35 AM, Finn Thain wrote:
> Merge the bus reset code from NCR5380.c into atari_NCR5380.c. This allows
> for removal of a lot of duplicated code conditional on the RESET_BOOT
> macro (in the next patch).
> 
> The atari_NCR5380.c fork lacks the do_reset() and NCR5380_poll_politely()
> routines from NCR5380.c, so introduce them. They are indispensible. Keep
> the two implementations in sync.
> 
> Signed-off-by: Finn Thain <fthain@telegraphics.com.au>
> 
> ---
>  drivers/scsi/NCR5380.c       |   33 +++++++-----
>  drivers/scsi/atari_NCR5380.c |  113 +++++++++++++++++++++++++++++++++++++++++++
>  2 files changed, 134 insertions(+), 12 deletions(-)
> 
Reviewed-by: Hannes Reinecke <hare@suse.com>

Cheers,

Hannes
-- 
Dr. Hannes Reinecke		               zSeries & Storage
hare@suse.de			               +49 911 74053 688
SUSE LINUX GmbH, Maxfeldstr. 5, 90409 Nürnberg
GF: F. Imendörffer, J. Smithard, J. Guild, D. Upmanyu, G. Norton
HRB 21284 (AG Nürnberg)

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

* Re: [PATCH 10/71] atari_NCR5380: Remove RESET_BOOT, CONFIG_ATARI_SCSI_TOSHIBA_DELAY and CONFIG_ATARI_SCSI_RESET_BOOT
  2015-11-18  8:35   ` Finn Thain
  (?)
  (?)
@ 2015-11-19 13:41   ` Hannes Reinecke
  -1 siblings, 0 replies; 268+ messages in thread
From: Hannes Reinecke @ 2015-11-19 13:41 UTC (permalink / raw)
  To: Finn Thain, James E.J. Bottomley, Michael Schmitz, linux-m68k,
	linux-scsi, linux-kernel

On 11/18/2015 09:35 AM, Finn Thain wrote:
> The atari_NCR5380.c core driver now takes care of bus reset upon driver
> initialization if required (same as NCR5380.c). Move the Toshiba CD-ROM
> support into the core driver, enabled with a host flag, so that all
> NCR5380 drivers can make use of it.
> 
> Drop the RESET_BOOT macros and the ATARI_SCSI_RESET_BOOT and 
> ATARI_SCSI_TOSHIBA_DELAY Kconfig symbols, which are now redundant.
> 
> Remove the atari_scsi_reset_boot(), mac_scsi_reset_boot() and
> sun3_scsi_reset_boot() routines. None of this duplicated code is needed
> now that all drivers can use NCR5380_maybe_reset_bus().
> 
> This brings atari_scsi, mac_scsi and sun3_scsi into line with all of the
> other NCR5380 drivers.
> 
> The bus reset may raise an interrupt. That would be new behaviour for
> atari_scsi only when CONFIG_ATARI_SCSI_RESET_BOOT=n. The ST DMA interrupt
> is not assigned to atari_scsi at this stage, so
> CONFIG_ATARI_SCSI_RESET_BOOT=y may well be problematic already.
> Regardless, do_reset() now raises and clears the interrupt within
> local_irq_save/restore which should avoid problems.
> 
> Signed-off-by: Finn Thain <fthain@telegraphics.com.au>
> 
> ---
>  drivers/scsi/Kconfig         |   17 -----------
>  drivers/scsi/NCR5380.c       |   17 +++++++++--
>  drivers/scsi/NCR5380.h       |    1 
>  drivers/scsi/atari_NCR5380.c |   22 +++++++++-----
>  drivers/scsi/atari_scsi.c    |   60 +++++----------------------------------
>  drivers/scsi/mac_scsi.c      |   65 ++++++-------------------------------------
>  drivers/scsi/sun3_scsi.c     |   47 -------------------------------
>  7 files changed, 51 insertions(+), 178 deletions(-)
> 
Reviewed-by: Hannes Reinecke <hare@suse.com>

Cheers,

Hannes
-- 
Dr. Hannes Reinecke		               zSeries & Storage
hare@suse.de			               +49 911 74053 688
SUSE LINUX GmbH, Maxfeldstr. 5, 90409 Nürnberg
GF: F. Imendörffer, J. Smithard, J. Guild, D. Upmanyu, G. Norton
HRB 21284 (AG Nürnberg)

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

* Re: [PATCH 11/71] ncr5380: Simplify bus reset handlers
  2015-11-18  8:35   ` Finn Thain
@ 2015-11-19 13:56     ` Hannes Reinecke
  -1 siblings, 0 replies; 268+ messages in thread
From: Hannes Reinecke @ 2015-11-19 13:56 UTC (permalink / raw)
  To: Finn Thain, James E.J. Bottomley, Michael Schmitz, linux-m68k,
	linux-scsi, linux-kernel

On 11/18/2015 09:35 AM, Finn Thain wrote:
> Make use of do_reset() in the bus reset handler in atari_NCR5380.c. The
> version in NCR5380.c already does so. Keep them in sync.
> 
> Signed-off-by: Finn Thain <fthain@telegraphics.com.au>
> 
> ---
> 
> Bus reset handlers in both core drivers still have serious problems for
> EH purposes. Those problems are addressed later in this series.
> 
> ---
>  drivers/scsi/NCR5380.c       |   20 +++++++++++---------
>  drivers/scsi/atari_NCR5380.c |   30 ++++++++++++------------------
>  2 files changed, 23 insertions(+), 27 deletions(-)
> 
Reviewed-by: Hannes Reinecke <hare@suse.com>

Cheers,

Hannes
-- 
Dr. Hannes Reinecke		               zSeries & Storage
hare@suse.de			               +49 911 74053 688
SUSE LINUX GmbH, Maxfeldstr. 5, 90409 Nürnberg
GF: F. Imendörffer, J. Smithard, J. Guild, D. Upmanyu, G. Norton
HRB 21284 (AG Nürnberg)

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

* Re: [PATCH 11/71] ncr5380: Simplify bus reset handlers
@ 2015-11-19 13:56     ` Hannes Reinecke
  0 siblings, 0 replies; 268+ messages in thread
From: Hannes Reinecke @ 2015-11-19 13:56 UTC (permalink / raw)
  To: Finn Thain, James E.J. Bottomley, Michael Schmitz, linux-m68k,
	linux-scsi, linux-kernel

On 11/18/2015 09:35 AM, Finn Thain wrote:
> Make use of do_reset() in the bus reset handler in atari_NCR5380.c. The
> version in NCR5380.c already does so. Keep them in sync.
> 
> Signed-off-by: Finn Thain <fthain@telegraphics.com.au>
> 
> ---
> 
> Bus reset handlers in both core drivers still have serious problems for
> EH purposes. Those problems are addressed later in this series.
> 
> ---
>  drivers/scsi/NCR5380.c       |   20 +++++++++++---------
>  drivers/scsi/atari_NCR5380.c |   30 ++++++++++++------------------
>  2 files changed, 23 insertions(+), 27 deletions(-)
> 
Reviewed-by: Hannes Reinecke <hare@suse.com>

Cheers,

Hannes
-- 
Dr. Hannes Reinecke		               zSeries & Storage
hare@suse.de			               +49 911 74053 688
SUSE LINUX GmbH, Maxfeldstr. 5, 90409 Nürnberg
GF: F. Imendörffer, J. Smithard, J. Guild, D. Upmanyu, G. Norton
HRB 21284 (AG Nürnberg)
--
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] 268+ messages in thread

* Re: [PATCH 12/71] ncr5380: Remove unused hostdata->aborted flag
  2015-11-18  8:35   ` Finn Thain
  (?)
@ 2015-11-19 14:13   ` Hannes Reinecke
  -1 siblings, 0 replies; 268+ messages in thread
From: Hannes Reinecke @ 2015-11-19 14:13 UTC (permalink / raw)
  To: Finn Thain, James E.J. Bottomley, Michael Schmitz, linux-m68k,
	linux-scsi, linux-kernel

On 11/18/2015 09:35 AM, Finn Thain wrote:
> The aborted flag was introduced in v1.1.38 but never used. Remove it.
> 
> Signed-off-by: Finn Thain <fthain@telegraphics.com.au>
> 
Reviewed-by: Hannes Reinecke <hare@suse.com>

Cheers,

Hannes
-- 
Dr. Hannes Reinecke		               zSeries & Storage
hare@suse.de			               +49 911 74053 688
SUSE LINUX GmbH, Maxfeldstr. 5, 90409 Nürnberg
GF: F. Imendörffer, J. Smithard, J. Guild, D. Upmanyu, G. Norton
HRB 21284 (AG Nürnberg)

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

* Re: [PATCH 13/71] ncr5380: Remove redundant register writes
  2015-11-18  8:35   ` Finn Thain
@ 2015-11-19 14:14     ` Hannes Reinecke
  -1 siblings, 0 replies; 268+ messages in thread
From: Hannes Reinecke @ 2015-11-19 14:14 UTC (permalink / raw)
  To: Finn Thain, James E.J. Bottomley, Michael Schmitz, linux-m68k,
	linux-scsi, linux-kernel

On 11/18/2015 09:35 AM, Finn Thain wrote:
> Remove the duplicate write to the Select Enable Register that appeared
> in v1.1.38.
> 
> Also remove the redundant write to Initiator Command Register prior to
> calling do_abort().
> 
> Signed-off-by: Finn Thain <fthain@telegraphics.com.au>
> 
> ---
Reviewed-by: Hannes Reinecke <hare@suse.com>

Cheers,

Hannes
-- 
Dr. Hannes Reinecke		               zSeries & Storage
hare@suse.de			               +49 911 74053 688
SUSE LINUX GmbH, Maxfeldstr. 5, 90409 Nürnberg
GF: F. Imendörffer, J. Smithard, J. Guild, D. Upmanyu, G. Norton
HRB 21284 (AG Nürnberg)

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

* Re: [PATCH 13/71] ncr5380: Remove redundant register writes
@ 2015-11-19 14:14     ` Hannes Reinecke
  0 siblings, 0 replies; 268+ messages in thread
From: Hannes Reinecke @ 2015-11-19 14:14 UTC (permalink / raw)
  To: Finn Thain, James E.J. Bottomley, Michael Schmitz, linux-m68k,
	linux-scsi, linux-kernel

On 11/18/2015 09:35 AM, Finn Thain wrote:
> Remove the duplicate write to the Select Enable Register that appeared
> in v1.1.38.
> 
> Also remove the redundant write to Initiator Command Register prior to
> calling do_abort().
> 
> Signed-off-by: Finn Thain <fthain@telegraphics.com.au>
> 
> ---
Reviewed-by: Hannes Reinecke <hare@suse.com>

Cheers,

Hannes
-- 
Dr. Hannes Reinecke		               zSeries & Storage
hare@suse.de			               +49 911 74053 688
SUSE LINUX GmbH, Maxfeldstr. 5, 90409 Nürnberg
GF: F. Imendörffer, J. Smithard, J. Guild, D. Upmanyu, G. Norton
HRB 21284 (AG Nürnberg)
--
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] 268+ messages in thread

* Re: [PATCH 14/71] ncr5380: Use return instead of goto in NCR5380_select()
  2015-11-18  8:35   ` Finn Thain
  (?)
@ 2015-11-19 14:14   ` Hannes Reinecke
  -1 siblings, 0 replies; 268+ messages in thread
From: Hannes Reinecke @ 2015-11-19 14:14 UTC (permalink / raw)
  To: Finn Thain, James E.J. Bottomley, Michael Schmitz, linux-m68k,
	linux-scsi, linux-kernel

On 11/18/2015 09:35 AM, Finn Thain wrote:
> The "failed" label in NCR5380_select() is not helpful. Some failures
> return 0, others -1. Use return instead of goto to improve clarity and
> brevity, like atari_NCR5380.c does. Fix the relevant comments.
> 
> Signed-off-by: Finn Thain <fthain@telegraphics.com.au>
> 
> ---
>  drivers/scsi/NCR5380.c       |   30 ++++++++----------------------
>  drivers/scsi/atari_NCR5380.c |    6 +++---
>  2 files changed, 11 insertions(+), 25 deletions(-)
> 
Reviewed-by: Hannes Reinecke <hare@suse.com>

Cheers,

Hannes
-- 
Dr. Hannes Reinecke		               zSeries & Storage
hare@suse.de			               +49 911 74053 688
SUSE LINUX GmbH, Maxfeldstr. 5, 90409 Nürnberg
GF: F. Imendörffer, J. Smithard, J. Guild, D. Upmanyu, G. Norton
HRB 21284 (AG Nürnberg)

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

* Re: [PATCH 15/71] ncr5380: Always escalate bad target time-out in NCR5380_select()
  2015-11-18  8:35   ` Finn Thain
@ 2015-11-19 14:15     ` Hannes Reinecke
  -1 siblings, 0 replies; 268+ messages in thread
From: Hannes Reinecke @ 2015-11-19 14:15 UTC (permalink / raw)
  To: Finn Thain, James E.J. Bottomley, Michael Schmitz, linux-m68k,
	linux-scsi, linux-kernel

On 11/18/2015 09:35 AM, Finn Thain wrote:
> Remove the restart_select and targets_present variables introduced in
> Linux v1.1.38. The former was used only for a questionable debug printk
> and the latter "so we can call a select failure a retryable condition".
> Well, retrying select failure in general is a different problem to a
> target that doesn't assert BSY. We need to handle these two cases
> differently; the latter case can be left to the SCSI ML.
> 
> Signed-off-by: Finn Thain <fthain@telegraphics.com.au>
> 
> ---
>  drivers/scsi/NCR5380.c       |   13 -------------
>  drivers/scsi/NCR5380.h       |    6 ------
>  drivers/scsi/atari_NCR5380.c |   13 -------------
>  3 files changed, 32 deletions(-)
> 
Reviewed-by: Hannes Reinecke <hare@suse.com>

Cheers,

Hannes
-- 
Dr. Hannes Reinecke		               zSeries & Storage
hare@suse.de			               +49 911 74053 688
SUSE LINUX GmbH, Maxfeldstr. 5, 90409 Nürnberg
GF: F. Imendörffer, J. Smithard, J. Guild, D. Upmanyu, G. Norton
HRB 21284 (AG Nürnberg)

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

* Re: [PATCH 15/71] ncr5380: Always escalate bad target time-out in NCR5380_select()
@ 2015-11-19 14:15     ` Hannes Reinecke
  0 siblings, 0 replies; 268+ messages in thread
From: Hannes Reinecke @ 2015-11-19 14:15 UTC (permalink / raw)
  To: Finn Thain, James E.J. Bottomley, Michael Schmitz, linux-m68k,
	linux-scsi, linux-kernel

On 11/18/2015 09:35 AM, Finn Thain wrote:
> Remove the restart_select and targets_present variables introduced in
> Linux v1.1.38. The former was used only for a questionable debug printk
> and the latter "so we can call a select failure a retryable condition".
> Well, retrying select failure in general is a different problem to a
> target that doesn't assert BSY. We need to handle these two cases
> differently; the latter case can be left to the SCSI ML.
> 
> Signed-off-by: Finn Thain <fthain@telegraphics.com.au>
> 
> ---
>  drivers/scsi/NCR5380.c       |   13 -------------
>  drivers/scsi/NCR5380.h       |    6 ------
>  drivers/scsi/atari_NCR5380.c |   13 -------------
>  3 files changed, 32 deletions(-)
> 
Reviewed-by: Hannes Reinecke <hare@suse.com>

Cheers,

Hannes
-- 
Dr. Hannes Reinecke		               zSeries & Storage
hare@suse.de			               +49 911 74053 688
SUSE LINUX GmbH, Maxfeldstr. 5, 90409 Nürnberg
GF: F. Imendörffer, J. Smithard, J. Guild, D. Upmanyu, G. Norton
HRB 21284 (AG Nürnberg)
--
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] 268+ messages in thread

* Re: [PATCH 16/71] ncr5380: Proceed with next command after NCR5380_select() calls scsi_done
  2015-11-18  8:35   ` Finn Thain
  (?)
@ 2015-11-19 14:16   ` Hannes Reinecke
  -1 siblings, 0 replies; 268+ messages in thread
From: Hannes Reinecke @ 2015-11-19 14:16 UTC (permalink / raw)
  To: Finn Thain, James E.J. Bottomley, Michael Schmitz, linux-m68k,
	linux-scsi, linux-kernel

On 11/18/2015 09:35 AM, Finn Thain wrote:
> If a target disappears from the SCSI bus, NCR5380_select() may
> subsequently fail with a time-out. In this situation, scsi_done is
> called and NCR5380_select() returns 0. Both hostdata->connected and
> hostdata->selecting are NULL and the main loop should proceed with
> the next command in the issue queue. Clarify this logic.
> 
> Signed-off-by: Finn Thain <fthain@telegraphics.com.au>
> 
> ---
> 
Reviewed-by: Hannes Reinecke <hare@suse.com>

Cheers,

Hannes
-- 
Dr. Hannes Reinecke		               zSeries & Storage
hare@suse.de			               +49 911 74053 688
SUSE LINUX GmbH, Maxfeldstr. 5, 90409 Nürnberg
GF: F. Imendörffer, J. Smithard, J. Guild, D. Upmanyu, G. Norton
HRB 21284 (AG Nürnberg)

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

* Re: [PATCH 00/71] More fixes, cleanup and modernization for NCR5380 drivers
  2015-11-19  2:24   ` Finn Thain
  2015-11-19  2:52     ` Michael Schmitz
  2015-11-19  7:48     ` Ondrej Zary
@ 2015-11-19 22:50     ` Ondrej Zary
  2015-11-20  1:41       ` Finn Thain
  2 siblings, 1 reply; 268+ messages in thread
From: Ondrej Zary @ 2015-11-19 22:50 UTC (permalink / raw)
  To: Finn Thain
  Cc: Sam Creasey, Michael Schmitz, James E.J. Bottomley, linux-m68k,
	linux-scsi, linux-kernel



On Thursday 19 November 2015 03:24:56 Finn Thain wrote:
> On Wed, 18 Nov 2015, Ondrej Zary wrote:
> > On Wednesday 18 November 2015, Finn Thain wrote:
> > > Like my previous work on the NCR5380 drivers, this patch series has
> > > bug fixes, code cleanup and modernization. These drivers suffer from
> > > mistakes, poor style and neglect and this long series addresses the
> > > worst of it, covering all ten wrapper drivers and both of the core
> > > driver forks. The combined size of the drivers is reduced by about 750
> > > LoC.
> > >
> > > This series continues to reduce divergence between the two core driver
> > > forks, often by copying a bug fix from one to the other. Most patches
> > > are larger for having to keep the two forks in sync. Making the same
> > > change to both is churn if one of them is to be removed but neither
> > > can be as yet. By the end of this series the diff between the two
> > > forks is minimal, so it becomes clear what caused the fork and what
> > > can be done about it.
> > >
> > > This patch series did benefit from scripts/checkpatch.pl but not too
> > > much. Decades ago, these drivers started out with 4-space tabs and if
> > > the 80 column limit were to be strictly enforced now, it would require
> > > adding new functions and shortening identifiers. I would defer this
> > > sort of activity until after the fork has been resolved.
> > >
> > > I have compile-tested all patches to all NCR5380 drivers (x86, ARM,
> > > m68k) and regression tested mac_scsi and dmx3191d modules on suitable
> > > hardware. Testing the mac_scsi and dmx3191d modules provides only
> > > limited coverage. It would be good to see some testing of ISA cards
> > > and Sun 3 and Atari hardware too (I don't have any).
> >
> > I have some NCR5380 ISA cards and can test them.
>
> Thanks Ondrej. I've no idea which ISA drivers are presently working in
> mainline. Finding regressions may be more difficult than usual ;-)

You're right... looks very broken:

[   62.577194] scsi host2: Generic NCR5380/NCR53C400 SCSI, io_port 0x240, n_io_port 16, base 0x0, irq 0, can_queue 16, cmd_per_lun 2, 
sg_tablesize 128, this_id 7, flags { DTC3181E NO_PSEUDO_DMA }, USLEEP_POLL 3, USLEEP_WAITLONG 1250, options { AUTOPROBE_IRQ PSEUDO_DMA 
NCR53C400 }
[   62.796635] scsi 2:0:0:0: Direct-Access     IBM      0663             e    PQ: 0 ANSI: 2
[   63.878494] sd 2:0:0:0: Attached scsi generic sg1 type 0
[   95.848260] sd 2:0:0:0: aborting command

And the system hangs completely.

It's much better with your patches, but still not great :)

[   93.963264] pnp 01:01.00: [io  0x0240-0x025f]
[   93.963493] pnp 01:01.00: [irq 5]
[   93.965768] pnp 01:01.00: activated
[   93.977147] scsi host2: Generic NCR5380/NCR53C400 SCSI, io_port 0x240, n_io_port 16, base 0x0, irq 0, can_queue 16, cmd_per_lun 2, 
sg_tablesize 128, this_id 7, flags { DTC3181E NO_PSEUDO_DMA }, options { AUTOPROBE_IRQ PSEUDO_DMA }
[   93.987527] scsi host2: rejecting message
[   93.987647] Synchronous Data Transfer Request period = 100 ns offset = 12
[   94.001219] scsi 2:0:0:0: Direct-Access     IBM      0663             e    PQ: 0 ANSI: 2
[  113.000794] sd 2:0:0:0: Attached scsi generic sg1 type 0
[  144.852432] sd 2:0:0:0: [sdb] Unit Not Ready
[  144.852574] sd 2:0:0:0: [sdb] Sense Key : Aborted Command [current]
[  144.852713] sd 2:0:0:0: [sdb] Add. Sense: Select or reselect failure
[  240.108292] INFO: task modprobe:1957 blocked for more than 120 seconds.
[  240.108418]       Not tainted 4.3.0-rc1+ #74
[  240.108501] "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message.
[  240.108597] modprobe        D 0000001a     0  1957   1950 0x00000000
[  240.108790]  ce0fad00 00000086 53881781 0000001a c1525f88 4edbe39c 0000001a 04ac33e5
[  240.109246]  00000000 ccd54000 ffffffff ffffffff d204b280 c139c504 00000000 c104416d
[  240.109699]  00000000 ce0fad00 c1054a45 c151fd8c c151fd8c d204b280 00000000 ccd6d100
[  240.110156] Call Trace:
[  240.110295]  [<c139c504>] ? schedule+0x5b/0x67
[  240.110430]  [<c104416d>] ? async_synchronize_cookie_domain+0x73/0x9f
[  240.110569]  [<c1054a45>] ? abort_exclusive_wait+0x6e/0x6e
[  240.110699]  [<c10ac9bc>] ? do_init_module+0xa4/0x1a3
[  240.110824]  [<c107ddb5>] ? load_module+0x14de/0x18ca
[  240.110948]  [<c107e2a0>] ? SyS_finit_module+0x47/0x56
[  240.111068]  [<c139e2c0>] ? sysenter_do_call+0x12/0x12
[  240.852458] sd 2:0:0:0: [sdb] Read Capacity(10) failed: Result: hostbyte=DID_TIME_OUT driverbyte=DRIVER_SENSE
[  240.852620] sd 2:0:0:0: [sdb] Sense Key : Aborted Command [current]
[  240.852760] sd 2:0:0:0: [sdb] Add. Sense: Select or reselect failure
[  272.852471] sd 2:0:0:0: [sdb] Write Protect is off
[  272.852614] sd 2:0:0:0: [sdb] Mode Sense: 00 00 00 00
[  304.084452] sd 2:0:0:0: [sdb] Asking for cache data failed
[  304.084592] sd 2:0:0:0: [sdb] Assuming drive cache: write through
[  360.108284] INFO: task modprobe:1957 blocked for more than 120 seconds.
[  360.108409]       Not tainted 4.3.0-rc1+ #74
[  360.108492] "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message.
[  360.108591] modprobe        D 0000001a     0  1957   1950 0x00000000
[  360.108787]  ce0fad00 00000086 53881781 0000001a c1525f88 4edbe39c 0000001a 04ac33e5
[  360.109248]  00000000 ccd54000 ffffffff ffffffff d204b280 c139c504 00000000 c104416d
[  360.109703]  00000000 ce0fad00 c1054a45 c151fd8c c151fd8c d204b280 00000000 ccd6d100
[  360.110158] Call Trace:
[  360.110296]  [<c139c504>] ? schedule+0x5b/0x67
[  360.110430]  [<c104416d>] ? async_synchronize_cookie_domain+0x73/0x9f
[  360.110568]  [<c1054a45>] ? abort_exclusive_wait+0x6e/0x6e
[  360.110699]  [<c10ac9bc>] ? do_init_module+0xa4/0x1a3
[  360.110823]  [<c107ddb5>] ? load_module+0x14de/0x18ca
[  360.110945]  [<c107e2a0>] ? SyS_finit_module+0x47/0x56
[  360.111065]  [<c139e2c0>] ? sysenter_do_call+0x12/0x12
[  431.060488] sd 2:0:0:0: [sdb] Read Capacity(10) failed: Result: hostbyte=DID_TIME_OUT driverbyte=DRIVER_SENSE
[  431.060650] sd 2:0:0:0: [sdb] Sense Key : Aborted Command [current]
[  431.060791] sd 2:0:0:0: [sdb] Add. Sense: Select or reselect failure
[  480.108282] INFO: task modprobe:1957 blocked for more than 120 seconds.
[  480.108405]       Not tainted 4.3.0-rc1+ #74
[  480.108488] "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message.
[  480.108585] modprobe        D 0000001a     0  1957   1950 0x00000000
[  480.108779]  ce0fad00 00000086 53881781 0000001a c1525f88 4edbe39c 0000001a 04ac33e5
[  480.109236]  00000000 ccd54000 ffffffff ffffffff d204b280 c139c504 00000000 c104416d
[  480.109689]  00000000 ce0fad00 c1054a45 c151fd8c c151fd8c d204b280 00000000 ccd6d100
[  480.110145] Call Trace:
[  480.110282]  [<c139c504>] ? schedule+0x5b/0x67
[  480.110417]  [<c104416d>] ? async_synchronize_cookie_domain+0x73/0x9f
[  480.110556]  [<c1054a45>] ? abort_exclusive_wait+0x6e/0x6e
[  480.110685]  [<c10ac9bc>] ? do_init_module+0xa4/0x1a3
[  480.110810]  [<c107ddb5>] ? load_module+0x14de/0x18ca
[  480.110932]  [<c107e2a0>] ? SyS_finit_module+0x47/0x56
[  480.111052]  [<c139e2c0>] ? sysenter_do_call+0x12/0x12
[  495.062082] sd 2:0:0:0: [sdb] Attached SCSI disk

-- 
Ondrej Zary

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

* Re: [PATCH 00/71] More fixes, cleanup and modernization for NCR5380 drivers
  2015-11-19 22:50     ` Ondrej Zary
@ 2015-11-20  1:41       ` Finn Thain
  2015-11-20  7:21         ` Finn Thain
                           ` (2 more replies)
  0 siblings, 3 replies; 268+ messages in thread
From: Finn Thain @ 2015-11-20  1:41 UTC (permalink / raw)
  To: Ondrej Zary
  Cc: Sam Creasey, Michael Schmitz, James E.J. Bottomley, linux-m68k,
	linux-scsi, linux-kernel


On Thu, 19 Nov 2015, Ondrej Zary wrote:

> On Thursday 19 November 2015 03:24:56 Finn Thain wrote:
>
> > On Wed, 18 Nov 2015, Ondrej Zary wrote:
> >
> > >
> > > I have some NCR5380 ISA cards and can test them.
> >
> > Thanks Ondrej. I've no idea which ISA drivers are presently working in 
> > mainline. Finding regressions may be more difficult than usual ;-)
> 
> You're right... looks very broken:
> 
> [   62.577194] scsi host2: Generic NCR5380/NCR53C400 SCSI, io_port 0x240, n_io_port 16, base 0x0, irq 0, can_queue 16, cmd_per_lun 2, 
> sg_tablesize 128, this_id 7, flags { DTC3181E NO_PSEUDO_DMA }, USLEEP_POLL 3, USLEEP_WAITLONG 1250, options { AUTOPROBE_IRQ PSEUDO_DMA 
> NCR53C400 }
> [   62.796635] scsi 2:0:0:0: Direct-Access     IBM      0663             e    PQ: 0 ANSI: 2
> [   63.878494] sd 2:0:0:0: Attached scsi generic sg1 type 0
> [   95.848260] sd 2:0:0:0: aborting command
> 
> And the system hangs completely.
> 

Yes. That was the usual failure mode. The old EH abort routine is fatal. 
Up until I disabled PDMA by default for mac_scsi (in v3.19), that driver 
would do the same thing.

> It's much better with your patches, but still not great :)
> 

Pleased to hear it :)

> [   93.963264] pnp 01:01.00: [io  0x0240-0x025f]
> [   93.963493] pnp 01:01.00: [irq 5]
> [   93.965768] pnp 01:01.00: activated
> [   93.977147] scsi host2: Generic NCR5380/NCR53C400 SCSI, io_port 0x240, n_io_port 16, base 0x0, irq 0, can_queue 16, cmd_per_lun 2, 
> sg_tablesize 128, this_id 7, flags { DTC3181E NO_PSEUDO_DMA }, options { AUTOPROBE_IRQ PSEUDO_DMA }
> [   93.987527] scsi host2: rejecting message
> [   93.987647] Synchronous Data Transfer Request period = 100 ns offset = 12
> [   94.001219] scsi 2:0:0:0: Direct-Access     IBM      0663             e    PQ: 0 ANSI: 2
> [  113.000794] sd 2:0:0:0: Attached scsi generic sg1 type 0

I'd be interested to know what commands were in play in that 19 second 
interval. Might need to use scsi_logging_level to figure that out.

My tests involved 3 different scsi targets (two disks and a CD-ROM) but 
none of these send a SDTR. Your log says the driver correctly rejected the 
SDTR message but that doesn't mean the target actually went to MSG IN 
phase and got the message. Do you have any older targets you can test?

> [  144.852432] sd 2:0:0:0: [sdb] Unit Not Ready
> [  144.852574] sd 2:0:0:0: [sdb] Sense Key : Aborted Command [current]
> [  144.852713] sd 2:0:0:0: [sdb] Add. Sense: Select or reselect failure

AFAIK, the target should not have to abort any commands. Moreover, the 
target should never experience a select/reselect failure, because you have 
irq == 0 (see above) and that implies that the target is never permitted 
the disconnect privilege.

> [  240.108292] INFO: task modprobe:1957 blocked for more than 120 seconds.
> [  240.108418]       Not tainted 4.3.0-rc1+ #74

Why not use v4.3?

> [  240.108501] "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message.
> [  240.108597] modprobe        D 0000001a     0  1957   1950 0x00000000
> [  240.108790]  ce0fad00 00000086 53881781 0000001a c1525f88 4edbe39c 0000001a 04ac33e5
> [  240.109246]  00000000 ccd54000 ffffffff ffffffff d204b280 c139c504 00000000 c104416d
> [  240.109699]  00000000 ce0fad00 c1054a45 c151fd8c c151fd8c d204b280 00000000 ccd6d100
> [  240.110156] Call Trace:
> [  240.110295]  [<c139c504>] ? schedule+0x5b/0x67
> [  240.110430]  [<c104416d>] ? async_synchronize_cookie_domain+0x73/0x9f
> [  240.110569]  [<c1054a45>] ? abort_exclusive_wait+0x6e/0x6e
> [  240.110699]  [<c10ac9bc>] ? do_init_module+0xa4/0x1a3
> [  240.110824]  [<c107ddb5>] ? load_module+0x14de/0x18ca
> [  240.110948]  [<c107e2a0>] ? SyS_finit_module+0x47/0x56
> [  240.111068]  [<c139e2c0>] ? sysenter_do_call+0x12/0x12

Not sure what module was being probed here. I presume it was g_NCR5380 or 
g_NCR5380_mmio. Neither of these calls 'scsi_scan_host'. I'm not sure what 
the implications are (?)

> [  240.852458] sd 2:0:0:0: [sdb] Read Capacity(10) failed: Result: hostbyte=DID_TIME_OUT driverbyte=DRIVER_SENSE
> [  240.852620] sd 2:0:0:0: [sdb] Sense Key : Aborted Command [current]
> [  240.852760] sd 2:0:0:0: [sdb] Add. Sense: Select or reselect failure
> [  272.852471] sd 2:0:0:0: [sdb] Write Protect is off
> [  272.852614] sd 2:0:0:0: [sdb] Mode Sense: 00 00 00 00
> [  304.084452] sd 2:0:0:0: [sdb] Asking for cache data failed
> [  304.084592] sd 2:0:0:0: [sdb] Assuming drive cache: write through

This looks like nonsense to me ... I don't think the target actually 
aborted the reselection phase of a read capacity command. I'm out of ideas 
here. Can anyone else make sense of this?

> [  360.108284] INFO: task modprobe:1957 blocked for more than 120 seconds.
> [  360.108409]       Not tainted 4.3.0-rc1+ #74
> [  360.108492] "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message.
> [  360.108591] modprobe        D 0000001a     0  1957   1950 0x00000000
> [  360.108787]  ce0fad00 00000086 53881781 0000001a c1525f88 4edbe39c 0000001a 04ac33e5
> [  360.109248]  00000000 ccd54000 ffffffff ffffffff d204b280 c139c504 00000000 c104416d
> [  360.109703]  00000000 ce0fad00 c1054a45 c151fd8c c151fd8c d204b280 00000000 ccd6d100
> [  360.110158] Call Trace:
> [  360.110296]  [<c139c504>] ? schedule+0x5b/0x67
> [  360.110430]  [<c104416d>] ? async_synchronize_cookie_domain+0x73/0x9f
> [  360.110568]  [<c1054a45>] ? abort_exclusive_wait+0x6e/0x6e
> [  360.110699]  [<c10ac9bc>] ? do_init_module+0xa4/0x1a3
> [  360.110823]  [<c107ddb5>] ? load_module+0x14de/0x18ca
> [  360.110945]  [<c107e2a0>] ? SyS_finit_module+0x47/0x56
> [  360.111065]  [<c139e2c0>] ? sysenter_do_call+0x12/0x12
> [  431.060488] sd 2:0:0:0: [sdb] Read Capacity(10) failed: Result: hostbyte=DID_TIME_OUT driverbyte=DRIVER_SENSE
> [  431.060650] sd 2:0:0:0: [sdb] Sense Key : Aborted Command [current]
> [  431.060791] sd 2:0:0:0: [sdb] Add. Sense: Select or reselect failure
> [  480.108282] INFO: task modprobe:1957 blocked for more than 120 seconds.
> [  480.108405]       Not tainted 4.3.0-rc1+ #74
> [  480.108488] "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message.
> [  480.108585] modprobe        D 0000001a     0  1957   1950 0x00000000
> [  480.108779]  ce0fad00 00000086 53881781 0000001a c1525f88 4edbe39c 0000001a 04ac33e5
> [  480.109236]  00000000 ccd54000 ffffffff ffffffff d204b280 c139c504 00000000 c104416d
> [  480.109689]  00000000 ce0fad00 c1054a45 c151fd8c c151fd8c d204b280 00000000 ccd6d100
> [  480.110145] Call Trace:
> [  480.110282]  [<c139c504>] ? schedule+0x5b/0x67
> [  480.110417]  [<c104416d>] ? async_synchronize_cookie_domain+0x73/0x9f
> [  480.110556]  [<c1054a45>] ? abort_exclusive_wait+0x6e/0x6e
> [  480.110685]  [<c10ac9bc>] ? do_init_module+0xa4/0x1a3
> [  480.110810]  [<c107ddb5>] ? load_module+0x14de/0x18ca
> [  480.110932]  [<c107e2a0>] ? SyS_finit_module+0x47/0x56
> [  480.111052]  [<c139e2c0>] ? sysenter_do_call+0x12/0x12
> [  495.062082] sd 2:0:0:0: [sdb] Attached SCSI disk
> 
> 

-- 

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

* Re: [PATCH 00/71] More fixes, cleanup and modernization for NCR5380 drivers
  2015-11-20  1:41       ` Finn Thain
@ 2015-11-20  7:21         ` Finn Thain
  2015-11-20  7:33           ` Christoph Hellwig
  2015-11-20  7:35         ` Ondrej Zary
  2015-11-20 18:29         ` Ondrej Zary
  2 siblings, 1 reply; 268+ messages in thread
From: Finn Thain @ 2015-11-20  7:21 UTC (permalink / raw)
  To: Ondrej Zary
  Cc: Sam Creasey, Michael Schmitz, James E.J. Bottomley, linux-m68k,
	linux-scsi, linux-kernel


On Fri, 20 Nov 2015, I wrote:

> On Thu, 19 Nov 2015, Ondrej Zary wrote:
> 
> > [  240.108501] "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message.
> > [  240.108597] modprobe        D 0000001a     0  1957   1950 0x00000000
> > [  240.108790]  ce0fad00 00000086 53881781 0000001a c1525f88 4edbe39c 0000001a 04ac33e5
> > [  240.109246]  00000000 ccd54000 ffffffff ffffffff d204b280 c139c504 00000000 c104416d
> > [  240.109699]  00000000 ce0fad00 c1054a45 c151fd8c c151fd8c d204b280 00000000 ccd6d100
> > [  240.110156] Call Trace:
> > [  240.110295]  [<c139c504>] ? schedule+0x5b/0x67
> > [  240.110430]  [<c104416d>] ? async_synchronize_cookie_domain+0x73/0x9f
> > [  240.110569]  [<c1054a45>] ? abort_exclusive_wait+0x6e/0x6e
> > [  240.110699]  [<c10ac9bc>] ? do_init_module+0xa4/0x1a3
> > [  240.110824]  [<c107ddb5>] ? load_module+0x14de/0x18ca
> > [  240.110948]  [<c107e2a0>] ? SyS_finit_module+0x47/0x56
> > [  240.111068]  [<c139e2c0>] ? sysenter_do_call+0x12/0x12
> 
> Not sure what module was being probed here. I presume it was g_NCR5380 
> or g_NCR5380_mmio. Neither of these calls 'scsi_scan_host'. I'm not sure 
> what the implications are (?)

Nevermind. The call is in scsi_module.c.

-- 

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

* Re: [PATCH 00/71] More fixes, cleanup and modernization for NCR5380 drivers
  2015-11-20  7:21         ` Finn Thain
@ 2015-11-20  7:33           ` Christoph Hellwig
  2015-11-20  8:19             ` Finn Thain
  0 siblings, 1 reply; 268+ messages in thread
From: Christoph Hellwig @ 2015-11-20  7:33 UTC (permalink / raw)
  To: Finn Thain
  Cc: Ondrej Zary, Sam Creasey, Michael Schmitz, James E.J. Bottomley,
	linux-m68k, linux-scsi, linux-kernel

On Fri, Nov 20, 2015 at 06:21:06PM +1100, Finn Thain wrote:
> > Not sure what module was being probed here. I presume it was g_NCR5380 
> > or g_NCR5380_mmio. Neither of these calls 'scsi_scan_host'. I'm not sure 
> > what the implications are (?)
> 
> Nevermind. The call is in scsi_module.c.

Which, btw really need to go away.  If you want to resurrect the
ISA drivers they need to be converted to proper probing.

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

* Re: [PATCH 00/71] More fixes, cleanup and modernization for NCR5380 drivers
  2015-11-20  1:41       ` Finn Thain
  2015-11-20  7:21         ` Finn Thain
@ 2015-11-20  7:35         ` Ondrej Zary
  2015-11-20 18:29         ` Ondrej Zary
  2 siblings, 0 replies; 268+ messages in thread
From: Ondrej Zary @ 2015-11-20  7:35 UTC (permalink / raw)
  To: Finn Thain
  Cc: Sam Creasey, Michael Schmitz, James E.J. Bottomley, linux-m68k,
	linux-scsi, linux-kernel

On Friday 20 November 2015, Finn Thain wrote:
> 
> On Thu, 19 Nov 2015, Ondrej Zary wrote:
> 
> > On Thursday 19 November 2015 03:24:56 Finn Thain wrote:
> >
> > > On Wed, 18 Nov 2015, Ondrej Zary wrote:
> > >
> > > >
> > > > I have some NCR5380 ISA cards and can test them.
> > >
> > > Thanks Ondrej. I've no idea which ISA drivers are presently working in 
> > > mainline. Finding regressions may be more difficult than usual ;-)
> > 
> > You're right... looks very broken:
> > 
> > [   62.577194] scsi host2: Generic NCR5380/NCR53C400 SCSI, io_port 0x240, n_io_port 16, base 0x0, irq 0, can_queue 16, cmd_per_lun 2, 
> > sg_tablesize 128, this_id 7, flags { DTC3181E NO_PSEUDO_DMA }, USLEEP_POLL 3, USLEEP_WAITLONG 1250, options { AUTOPROBE_IRQ PSEUDO_DMA 
> > NCR53C400 }
> > [   62.796635] scsi 2:0:0:0: Direct-Access     IBM      0663             e    PQ: 0 ANSI: 2
> > [   63.878494] sd 2:0:0:0: Attached scsi generic sg1 type 0
> > [   95.848260] sd 2:0:0:0: aborting command
> > 
> > And the system hangs completely.
> > 
> 
> Yes. That was the usual failure mode. The old EH abort routine is fatal. 
> Up until I disabled PDMA by default for mac_scsi (in v3.19), that driver 
> would do the same thing.
> 
> > It's much better with your patches, but still not great :)
> > 
> 
> Pleased to hear it :)
> 
> > [   93.963264] pnp 01:01.00: [io  0x0240-0x025f]
> > [   93.963493] pnp 01:01.00: [irq 5]
> > [   93.965768] pnp 01:01.00: activated
> > [   93.977147] scsi host2: Generic NCR5380/NCR53C400 SCSI, io_port 0x240, n_io_port 16, base 0x0, irq 0, can_queue 16, cmd_per_lun 2, 
> > sg_tablesize 128, this_id 7, flags { DTC3181E NO_PSEUDO_DMA }, options { AUTOPROBE_IRQ PSEUDO_DMA }
> > [   93.987527] scsi host2: rejecting message
> > [   93.987647] Synchronous Data Transfer Request period = 100 ns offset = 12
> > [   94.001219] scsi 2:0:0:0: Direct-Access     IBM      0663             e    PQ: 0 ANSI: 2
> > [  113.000794] sd 2:0:0:0: Attached scsi generic sg1 type 0
> 
> I'd be interested to know what commands were in play in that 19 second 
> interval. Might need to use scsi_logging_level to figure that out.
> 
> My tests involved 3 different scsi targets (two disks and a CD-ROM) but 
> none of these send a SDTR. Your log says the driver correctly rejected the 
> SDTR message but that doesn't mean the target actually went to MSG IN 
> phase and got the message. Do you have any older targets you can test?

Yes, I have some older disks too and also CD-ROMs. This one was just handy in
an external enclosure (the card has only an external DB25 connector). It can
be opened easily so I'll test the other devices too.

> > [  144.852432] sd 2:0:0:0: [sdb] Unit Not Ready
> > [  144.852574] sd 2:0:0:0: [sdb] Sense Key : Aborted Command [current]
> > [  144.852713] sd 2:0:0:0: [sdb] Add. Sense: Select or reselect failure
> 
> AFAIK, the target should not have to abort any commands. Moreover, the 
> target should never experience a select/reselect failure, because you have 
> irq == 0 (see above) and that implies that the target is never permitted 
> the disconnect privilege.
> 
> > [  240.108292] INFO: task modprobe:1957 blocked for more than 120 seconds.
> > [  240.108418]       Not tainted 4.3.0-rc1+ #74
> 
> Why not use v4.3?

I had that already built so just quickly applied the patches and tested. I have
to update the git tree anyway as ACPI is broken.

> > [  240.108501] "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message.
> > [  240.108597] modprobe        D 0000001a     0  1957   1950 0x00000000
> > [  240.108790]  ce0fad00 00000086 53881781 0000001a c1525f88 4edbe39c 0000001a 04ac33e5
> > [  240.109246]  00000000 ccd54000 ffffffff ffffffff d204b280 c139c504 00000000 c104416d
> > [  240.109699]  00000000 ce0fad00 c1054a45 c151fd8c c151fd8c d204b280 00000000 ccd6d100
> > [  240.110156] Call Trace:
> > [  240.110295]  [<c139c504>] ? schedule+0x5b/0x67
> > [  240.110430]  [<c104416d>] ? async_synchronize_cookie_domain+0x73/0x9f
> > [  240.110569]  [<c1054a45>] ? abort_exclusive_wait+0x6e/0x6e
> > [  240.110699]  [<c10ac9bc>] ? do_init_module+0xa4/0x1a3
> > [  240.110824]  [<c107ddb5>] ? load_module+0x14de/0x18ca
> > [  240.110948]  [<c107e2a0>] ? SyS_finit_module+0x47/0x56
> > [  240.111068]  [<c139e2c0>] ? sysenter_do_call+0x12/0x12
> 
> Not sure what module was being probed here. I presume it was g_NCR5380 or 
> g_NCR5380_mmio. Neither of these calls 'scsi_scan_host'. I'm not sure what 
> the implications are (?)

It was g_NCR5380 (DTCT-436P card).

> > [  240.852458] sd 2:0:0:0: [sdb] Read Capacity(10) failed: Result: hostbyte=DID_TIME_OUT driverbyte=DRIVER_SENSE
> > [  240.852620] sd 2:0:0:0: [sdb] Sense Key : Aborted Command [current]
> > [  240.852760] sd 2:0:0:0: [sdb] Add. Sense: Select or reselect failure
> > [  272.852471] sd 2:0:0:0: [sdb] Write Protect is off
> > [  272.852614] sd 2:0:0:0: [sdb] Mode Sense: 00 00 00 00
> > [  304.084452] sd 2:0:0:0: [sdb] Asking for cache data failed
> > [  304.084592] sd 2:0:0:0: [sdb] Assuming drive cache: write through
> 
> This looks like nonsense to me ... I don't think the target actually 
> aborted the reselection phase of a read capacity command. I'm out of ideas 
> here. Can anyone else make sense of this?


-- 
Ondrej Zary

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

* Re: [PATCH 00/71] More fixes, cleanup and modernization for NCR5380 drivers
  2015-11-20  7:33           ` Christoph Hellwig
@ 2015-11-20  8:19             ` Finn Thain
  2015-11-20  9:16               ` Ondrej Zary
  2015-11-20 10:00               ` Christoph Hellwig
  0 siblings, 2 replies; 268+ messages in thread
From: Finn Thain @ 2015-11-20  8:19 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: Ondrej Zary, Sam Creasey, Michael Schmitz, James E.J. Bottomley,
	linux-m68k, linux-scsi, linux-kernel


On Thu, 19 Nov 2015, Christoph Hellwig wrote:

> On Fri, Nov 20, 2015 at 06:21:06PM +1100, Finn Thain wrote:
>
> > > Not sure what module was being probed here. I presume it was 
> > > g_NCR5380 or g_NCR5380_mmio. Neither of these calls 
> > > 'scsi_scan_host'. I'm not sure what the implications are (?)
> > 
> > Nevermind. The call is in scsi_module.c.
> 
> Which, btw really need to go away.  If you want to resurrect the
> ISA drivers they need to be converted to proper probing.

Yes. I didn't do that conversion because I don't have ISA hardware and I 
don't understand ISA probing.

The present patch set doesn't seek to resurrect the ISA drivers. But I am 
trying to avoid regressions.

I have mixed feelings about the ISA drivers. ISA DMA support complicates 
things (it was never completed) and DMA seems to be the main obstacle to 
merging the two core driver forks.

-- 

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

* Re: [PATCH 00/71] More fixes, cleanup and modernization for NCR5380 drivers
  2015-11-20  8:19             ` Finn Thain
@ 2015-11-20  9:16               ` Ondrej Zary
  2015-11-20 10:00               ` Christoph Hellwig
  1 sibling, 0 replies; 268+ messages in thread
From: Ondrej Zary @ 2015-11-20  9:16 UTC (permalink / raw)
  To: Finn Thain
  Cc: Christoph Hellwig, Sam Creasey, Michael Schmitz,
	James E.J. Bottomley, linux-m68k, linux-scsi, linux-kernel

On Friday 20 November 2015, Finn Thain wrote:
> 
> On Thu, 19 Nov 2015, Christoph Hellwig wrote:
> 
> > On Fri, Nov 20, 2015 at 06:21:06PM +1100, Finn Thain wrote:
> >
> > > > Not sure what module was being probed here. I presume it was 
> > > > g_NCR5380 or g_NCR5380_mmio. Neither of these calls 
> > > > 'scsi_scan_host'. I'm not sure what the implications are (?)
> > > 
> > > Nevermind. The call is in scsi_module.c.
> > 
> > Which, btw really need to go away.  If you want to resurrect the
> > ISA drivers they need to be converted to proper probing.
> 
> Yes. I didn't do that conversion because I don't have ISA hardware and I 
> don't understand ISA probing.
> 
> The present patch set doesn't seek to resurrect the ISA drivers. But I am 
> trying to avoid regressions.
> 
> I have mixed feelings about the ISA drivers. ISA DMA support complicates 
> things (it was never completed) and DMA seems to be the main obstacle to 
> merging the two core driver forks.

IIRC, my ISA cards can't do DMA either.

-- 
Ondrej Zary

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

* Re: [PATCH 00/71] More fixes, cleanup and modernization for NCR5380 drivers
  2015-11-20  8:19             ` Finn Thain
  2015-11-20  9:16               ` Ondrej Zary
@ 2015-11-20 10:00               ` Christoph Hellwig
  2015-11-20 10:53                 ` Finn Thain
  1 sibling, 1 reply; 268+ messages in thread
From: Christoph Hellwig @ 2015-11-20 10:00 UTC (permalink / raw)
  To: Finn Thain
  Cc: Christoph Hellwig, Ondrej Zary, Sam Creasey, Michael Schmitz,
	James E.J. Bottomley, linux-m68k, linux-scsi, linux-kernel

On Fri, Nov 20, 2015 at 07:19:21PM +1100, Finn Thain wrote:
> Yes. I didn't do that conversion because I don't have ISA hardware and I 
> don't understand ISA probing.
> 
> The present patch set doesn't seek to resurrect the ISA drivers. But I am 
> trying to avoid regressions.
> 
> I have mixed feelings about the ISA drivers. ISA DMA support complicates 
> things (it was never completed) and DMA seems to be the main obstacle to 
> merging the two core driver forks.

I'd love to be able to get rid of the ISA drivers to be honest.  Given
that they appear to be gravely broken before your cleanups this might
be an opportunity to get rid of them.

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

* Re: [PATCH 00/71] More fixes, cleanup and modernization for NCR5380 drivers
  2015-11-20 10:00               ` Christoph Hellwig
@ 2015-11-20 10:53                 ` Finn Thain
  2015-11-20 11:40                   ` Ondrej Zary
  0 siblings, 1 reply; 268+ messages in thread
From: Finn Thain @ 2015-11-20 10:53 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: Ondrej Zary, Sam Creasey, Michael Schmitz, James E.J. Bottomley,
	linux-m68k, linux-scsi, linux-kernel


On Fri, 20 Nov 2015, Christoph Hellwig wrote:

> On Fri, Nov 20, 2015 at 07:19:21PM +1100, Finn Thain wrote:
>
> > Yes. I didn't do that conversion because I don't have ISA hardware and 
> > I don't understand ISA probing.
> > 
> > The present patch set doesn't seek to resurrect the ISA drivers. But I 
> > am trying to avoid regressions.
> > 
> > I have mixed feelings about the ISA drivers. ISA DMA support 
> > complicates things (it was never completed) and DMA seems to be the 
> > main obstacle to merging the two core driver forks.
> 
> I'd love to be able to get rid of the ISA drivers to be honest.

Is that because of their use of scsi_module.c or their general decrepitude 
or something else?

> Given that they appear to be gravely broken before your cleanups this 
> might be an opportunity to get rid of them.

At this stage, that's unclear (to me). It could be that g_NCR5380.c is not 
broken. It could be that the core driver can't handle certain targets. I 
think we need to do more testing.

-- 

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

* Re: [PATCH 00/71] More fixes, cleanup and modernization for NCR5380 drivers
  2015-11-20 10:53                 ` Finn Thain
@ 2015-11-20 11:40                   ` Ondrej Zary
  2015-11-20 11:45                     ` Christoph Hellwig
  2015-11-20 12:23                     ` Geert Uytterhoeven
  0 siblings, 2 replies; 268+ messages in thread
From: Ondrej Zary @ 2015-11-20 11:40 UTC (permalink / raw)
  To: Finn Thain
  Cc: Christoph Hellwig, Sam Creasey, Michael Schmitz,
	James E.J. Bottomley, linux-m68k, linux-scsi, linux-kernel

On Friday 20 November 2015, Finn Thain wrote:
> 
> On Fri, 20 Nov 2015, Christoph Hellwig wrote:
> 
> > On Fri, Nov 20, 2015 at 07:19:21PM +1100, Finn Thain wrote:
> >
> > > Yes. I didn't do that conversion because I don't have ISA hardware and 
> > > I don't understand ISA probing.
> > > 
> > > The present patch set doesn't seek to resurrect the ISA drivers. But I 
> > > am trying to avoid regressions.
> > > 
> > > I have mixed feelings about the ISA drivers. ISA DMA support 
> > > complicates things (it was never completed) and DMA seems to be the 
> > > main obstacle to merging the two core driver forks.
> > 
> > I'd love to be able to get rid of the ISA drivers to be honest.
> 
> Is that because of their use of scsi_module.c or their general decrepitude 
> or something else?

scsi_module.c usage shouldn't be hard to fix. I can do that after finding a working setup.

> > Given that they appear to be gravely broken before your cleanups this 
> > might be an opportunity to get rid of them.
> 
> At this stage, that's unclear (to me). It could be that g_NCR5380.c is not 
> broken. It could be that the core driver can't handle certain targets. I 
> think we need to do more testing.

Maybe I was just unlucky and tested a drive that never worked with this driver.

Working ISA means more testing possibilities. It's much easier to get an ISA card than a Sun or Atari. Also faster CPU (such as 1 GHz P3) means quicker testing.

-- 
Ondrej Zary

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

* Re: [PATCH 00/71] More fixes, cleanup and modernization for NCR5380 drivers
  2015-11-20 11:40                   ` Ondrej Zary
@ 2015-11-20 11:45                     ` Christoph Hellwig
  2015-11-20 12:23                     ` Geert Uytterhoeven
  1 sibling, 0 replies; 268+ messages in thread
From: Christoph Hellwig @ 2015-11-20 11:45 UTC (permalink / raw)
  To: Ondrej Zary
  Cc: Finn Thain, Christoph Hellwig, Sam Creasey, Michael Schmitz,
	James E.J. Bottomley, linux-m68k, linux-scsi, linux-kernel

On Fri, Nov 20, 2015 at 12:40:03PM +0100, Ondrej Zary wrote:
> > > I'd love to be able to get rid of the ISA drivers to be honest.
> > 
> > Is that because of their use of scsi_module.c or their general decrepitude 
> > or something else?
> 
> scsi_module.c usage shouldn't be hard to fix. I can do that after finding a working setup.

It's the general state of them.

> 
> > > Given that they appear to be gravely broken before your cleanups this 
> > > might be an opportunity to get rid of them.
> > 
> > At this stage, that's unclear (to me). It could be that g_NCR5380.c is not 
> > broken. It could be that the core driver can't handle certain targets. I 
> > think we need to do more testing.
> 
> Maybe I was just unlucky and tested a drive that never worked with this driver.
> 
> Working ISA means more testing possibilities. It's much easier to get an ISA card than a Sun or Atari. Also faster CPU (such as 1 GHz P3) means quicker testing.


Well, if you volunteer to bring the NCR5380 ISA drivers up to date and
maintain them it's obvuously fine to keep them around.

I'm more worried about all the unmaintained ISA drivers in horrible
shape.

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

* Re: [PATCH 00/71] More fixes, cleanup and modernization for NCR5380 drivers
  2015-11-20 11:40                   ` Ondrej Zary
  2015-11-20 11:45                     ` Christoph Hellwig
@ 2015-11-20 12:23                     ` Geert Uytterhoeven
  2015-11-20 12:46                       ` Ondrej Zary
  1 sibling, 1 reply; 268+ messages in thread
From: Geert Uytterhoeven @ 2015-11-20 12:23 UTC (permalink / raw)
  To: Ondrej Zary
  Cc: Finn Thain, Christoph Hellwig, Sam Creasey, Michael Schmitz,
	James E.J. Bottomley, Linux/m68k, scsi, linux-kernel

On Fri, Nov 20, 2015 at 12:40 PM, Ondrej Zary
<linux@rainbow-software.org> wrote:
> Working ISA means more testing possibilities. It's much easier to get an ISA card than a Sun or Atari. Also faster CPU (such as 1 GHz P3) means quicker testing.

Faster PCs without ISA slots? ;-)

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] 268+ messages in thread

* Re: [PATCH 00/71] More fixes, cleanup and modernization for NCR5380 drivers
  2015-11-20 12:23                     ` Geert Uytterhoeven
@ 2015-11-20 12:46                       ` Ondrej Zary
  0 siblings, 0 replies; 268+ messages in thread
From: Ondrej Zary @ 2015-11-20 12:46 UTC (permalink / raw)
  To: Geert Uytterhoeven
  Cc: Finn Thain, Christoph Hellwig, Sam Creasey, Michael Schmitz,
	James E.J. Bottomley, Linux/m68k, scsi, linux-kernel

On Friday 20 November 2015, Geert Uytterhoeven wrote:
> On Fri, Nov 20, 2015 at 12:40 PM, Ondrej Zary
> <linux@rainbow-software.org> wrote:
> > Working ISA means more testing possibilities. It's much easier to get an ISA card than a Sun or Atari. Also faster CPU (such as 1 GHz P3) means quicker testing.
> 
> Faster PCs without ISA slots? ;-)

Faster but not too fast, you have to be careful :)
There are many boards for Pentium 3 or Ahlon XP CPUs with ISA slots.

-- 
Ondrej Zary

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

* Re: [PATCH 00/71] More fixes, cleanup and modernization for NCR5380 drivers
  2015-11-20  1:41       ` Finn Thain
  2015-11-20  7:21         ` Finn Thain
  2015-11-20  7:35         ` Ondrej Zary
@ 2015-11-20 18:29         ` Ondrej Zary
  2015-11-21  1:58           ` Finn Thain
  2 siblings, 1 reply; 268+ messages in thread
From: Ondrej Zary @ 2015-11-20 18:29 UTC (permalink / raw)
  To: Finn Thain
  Cc: Sam Creasey, Michael Schmitz, James E.J. Bottomley, linux-m68k,
	linux-scsi, linux-kernel

On Friday 20 November 2015 02:41:19 Finn Thain wrote:
> 
> On Thu, 19 Nov 2015, Ondrej Zary wrote:
> 
> > On Thursday 19 November 2015 03:24:56 Finn Thain wrote:
> >
> > > On Wed, 18 Nov 2015, Ondrej Zary wrote:
> > >
> > > >
> > > > I have some NCR5380 ISA cards and can test them.
> > >
> > > Thanks Ondrej. I've no idea which ISA drivers are presently working in 
> > > mainline. Finding regressions may be more difficult than usual ;-)
> > 
> > You're right... looks very broken:
> > 
> > [   62.577194] scsi host2: Generic NCR5380/NCR53C400 SCSI, io_port 0x240, n_io_port 16, base 0x0, irq 0, can_queue 16, cmd_per_lun 2, 
> > sg_tablesize 128, this_id 7, flags { DTC3181E NO_PSEUDO_DMA }, USLEEP_POLL 3, USLEEP_WAITLONG 1250, options { AUTOPROBE_IRQ PSEUDO_DMA 
> > NCR53C400 }
> > [   62.796635] scsi 2:0:0:0: Direct-Access     IBM      0663             e    PQ: 0 ANSI: 2
> > [   63.878494] sd 2:0:0:0: Attached scsi generic sg1 type 0
> > [   95.848260] sd 2:0:0:0: aborting command
> > 
> > And the system hangs completely.
> > 
> 
> Yes. That was the usual failure mode. The old EH abort routine is fatal. 
> Up until I disabled PDMA by default for mac_scsi (in v3.19), that driver 
> would do the same thing.
> 
> > It's much better with your patches, but still not great :)
> > 
> 
> Pleased to hear it :)
> 
> > [   93.963264] pnp 01:01.00: [io  0x0240-0x025f]
> > [   93.963493] pnp 01:01.00: [irq 5]
> > [   93.965768] pnp 01:01.00: activated
> > [   93.977147] scsi host2: Generic NCR5380/NCR53C400 SCSI, io_port 0x240, n_io_port 16, base 0x0, irq 0, can_queue 16, cmd_per_lun 2, 
> > sg_tablesize 128, this_id 7, flags { DTC3181E NO_PSEUDO_DMA }, options { AUTOPROBE_IRQ PSEUDO_DMA }
> > [   93.987527] scsi host2: rejecting message
> > [   93.987647] Synchronous Data Transfer Request period = 100 ns offset = 12
> > [   94.001219] scsi 2:0:0:0: Direct-Access     IBM      0663             e    PQ: 0 ANSI: 2
> > [  113.000794] sd 2:0:0:0: Attached scsi generic sg1 type 0
> 
> I'd be interested to know what commands were in play in that 19 second 
> interval. Might need to use scsi_logging_level to figure that out.
> 
> My tests involved 3 different scsi targets (two disks and a CD-ROM) but 
> none of these send a SDTR. Your log says the driver correctly rejected the 
> SDTR message but that doesn't mean the target actually went to MSG IN 
> phase and got the message. Do you have any older targets you can test?

Another disk, without patches:

[   84.481582] pnp 01:01.00: activated
[   84.489650] scsi host2: Generic NCR5380/NCR53C400 SCSI, io_port 0x240, n_io_port 16, base 0x0, irq 0, can_queue 16, cmd_per_lun 2, sg_tablesize 128, this_id 7, flags { DTC3181E NO_PSEUDO_DMA }, USLEEP_POLL 3, USLEEP_WAITLONG 1250, options { AUTOPROBE_IRQ PSEUDO_DMA NCR53C400 }
[   84.953332] scsi 2:0:1:0: Direct-Access     QUANTUM  LP240S GM240S01X 4.6  PQ: 0 ANSI: 2 CCS
[   86.786475] sd 2:0:1:0: Attached scsi generic sg1 type 0
[   86.793753] sd 2:0:1:0: [sdb] 479350 512-byte logical blocks: (245 MB/234 MiB)
[   86.998555] sd 2:0:1:0: [sdb] Write Protect is off
[   87.406068] sd 2:0:1:0: [sdb] Write cache: enabled, read cache: enabled, doesn't support DPO or FUA
[  118.888271] sd 2:0:1:0: [sdb] aborting command
[  118.888738] sd 2:0:1:0: [sdb] aborting command

With patches:

[  258.473748] pnp 01:01.00: activated
[  258.483592] scsi host2: Generic NCR5380/NCR53C400 SCSI, io_port 0x240, n_io_port 16, base 0x0, irq 0, can_queue 16, cmd_per_lun 2, sg_tablesize 128, this_id 7, flags { DTC3181E NO_PSEUDO_DMA }, options { AUTOPROBE_IRQ PSEUDO_DMA }
[  261.347632] scsi 2:0:1:0: Direct-Access     QUANTUM  LP240S GM240S01X 4.6  PQ: 0 ANSI: 2 CCS
[  275.560451] sd 2:0:1:0: Attached scsi generic sg1 type 0
[  275.632519] sd 2:0:1:0: [sdb] 479350 512-byte logical blocks: (245 MB/234 MiB)
[  275.635533] sd 2:0:1:0: [sdb] Write Protect is off
[  275.642315] sd 2:0:1:0: [sdb] Write cache: enabled, read cache: enabled, doesn't support DPO or FUA
[  469.076347] sd 2:0:1:0: [sdb] FAILED Result: hostbyte=DID_TIME_OUT driverbyte=DRIVER_SENSE
[  469.076613] sd 2:0:1:0: [sdb] Sense Key : Aborted Command [current]
[  469.076851] sd 2:0:1:0: [sdb] Add. Sense: No additional sense information
[  469.077086] sd 2:0:1:0: [sdb] CDB: Read(10) 28 00 00 00 00 02 00 00 02 00
[  469.077306] blk_update_request: I/O error, dev sdb, sector 2
[  469.077522] Buffer I/O error on dev sdb, logical block 1, async page read
[  480.108255] INFO: task kworker/u2:2:60 blocked for more than 120 seconds.
[  480.109773]       Not tainted 4.3.0-rc1+ #74
[  480.109973] "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message.
[  480.110179] kworker/u2:2    D 00000040     0    60      2 0x00000000
[  480.110671] Workqueue: events_unbound async_run_entry_fn
[  480.110999]  cf9e8780 00000046 2eff25f7 00000040 c117f111 2ee82733 00000040 0016fec4
[  480.112390]  00000000 cfaa6000 00000000 7fffffff c139c7d2 c139c504 7fffffff c139d9d3
[  480.113661]  00000040 cfaa5cfc c106f460 00161108 00000000 0000c648 2106dcce 00000040
[  480.114893] Call Trace:
[  480.115124]  [<c117f111>] ? blk_queue_bio+0x1e8/0x1fb
[  480.115344]  [<c139c7d2>] ? bit_wait_io_timeout+0x3d/0x3d
[  480.115564]  [<c139c504>] ? schedule+0x5b/0x67
[  480.115794]  [<c139d9d3>] ? schedule_timeout+0x13/0xc5
[  480.116007]  [<c106f460>] ? timekeeping_get_ns+0x10/0x69
[  480.116406]  [<c139c7d2>] ? bit_wait_io_timeout+0x3d/0x3d
[  480.116636]  [<c106fae7>] ? ktime_get+0x38/0x48
[  480.116843]  [<c139bf83>] ? io_schedule_timeout+0x83/0xd7
[  480.117062]  [<c139c7f3>] ? bit_wait_io+0x21/0x26
[  480.117256]  [<c139c697>] ? __wait_on_bit+0x2f/0x5a
[  480.117486]  [<c10ff1eb>] ? blkdev_readpages+0x15/0x15
[  480.117704]  [<c10ad361>] ? wait_on_page_bit+0x57/0x5e
[  480.117942]  [<c1054a98>] ? wake_atomic_t_function+0x2a/0x2a
[  480.118151]  [<c10ad386>] ? wait_on_page_read+0xf/0x2a
[  480.118373]  [<c10ae0e1>] ? do_read_cache_page+0x8e/0x116
[  480.118587]  [<c10ff1eb>] ? blkdev_readpages+0x15/0x15
[  480.118809]  [<c10ae192>] ? read_cache_page+0x14/0x18
[  480.119008]  [<c1189b0e>] ? read_dev_sector+0x25/0x57
[  480.119222]  [<c118a8a8>] ? adfspart_check_ICS+0x30/0x1ac
[  480.119438]  [<c119a3f1>] ? vsnprintf+0x78/0x25d
[  480.119671]  [<c119a614>] ? snprintf+0x16/0x18
[  480.119874]  [<c118a7ea>] ? check_partition+0xd7/0x165
[  480.120253]  [<c118a067>] ? rescan_partitions+0x95/0x283
[  480.120443]  [<c1254b50>] ? scsi_block_when_processing_errors+0x13/0xae
[  480.120693]  [<c139cbc6>] ? mutex_lock+0x9/0x21
[  480.120915]  [<c1100046>] ? __blkdev_get+0x155/0x2f6
[  480.121133]  [<c110032f>] ? blkdev_get+0x148/0x258
[  480.121350]  [<c10ec747>] ? unlock_new_inode+0x36/0x3c
[  480.121570]  [<c10ff106>] ? bdget+0xdc/0xe6
[  480.121761]  [<c118854f>] ? add_disk+0x221/0x368
[  480.121996]  [<c126321a>] ? sd_probe_async+0xed/0x157
[  480.122214]  [<c10443a0>] ? async_run_entry_fn+0x2c/0xad
[  480.122437]  [<c103f060>] ? process_one_work+0x130/0x21f
[  480.122639]  [<c103f2f6>] ? worker_thread+0x18a/0x247
[  480.122854]  [<c103f16c>] ? process_scheduled_works+0x1d/0x1d
[  480.123069]  [<c1042c46>] ? kthread+0x7c/0x81
[  480.123288]  [<c139e201>] ? ret_from_kernel_thread+0x21/0x30
[  480.123493]  [<c1042bca>] ? kthread_parkme+0x11/0x11
[  480.123733] INFO: task modprobe:1977 blocked for more than 120 seconds.
[  480.123919]       Not tainted 4.3.0-rc1+ #74
[  480.124239] "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message.
[  480.124410] modprobe        D 00000040     0  1977   1969 0x00000000
[  480.124864]  cfb20000 00000086 29042653 00000040 c1525f88 28a83a17 00000040 005bec3c
[  480.126123]  00000000 ccdd0000 ffffffff ffffffff d2057280 c139c504 00000000 c104416d
[  480.127354]  00000000 cfb20000 c1054a45 c151fd8c c151fd8c d2057280 00000000 ccd621f0
[  480.128746] Call Trace:
[  480.128961]  [<c139c504>] ? schedule+0x5b/0x67
[  480.129202]  [<c104416d>] ? async_synchronize_cookie_domain+0x73/0x9f
[  480.129449]  [<c1054a45>] ? abort_exclusive_wait+0x6e/0x6e
[  480.129667]  [<c10ac9bc>] ? do_init_module+0xa4/0x1a3
[  480.129899]  [<c107ddb5>] ? load_module+0x14de/0x18ca
[  480.130119]  [<c107e2a0>] ? SyS_finit_module+0x47/0x56
[  480.130346]  [<c139e2c0>] ? sysenter_do_call+0x12/0x12
[  502.100317] sd 2:0:1:0: [sdb] FAILED Result: hostbyte=DID_TIME_OUT driverbyte=DRIVER_SENSE
[  502.100578] sd 2:0:1:0: [sdb] Sense Key : Aborted Command [current]
[  502.100818] sd 2:0:1:0: [sdb] Add. Sense: No additional sense information
[  502.101057] sd 2:0:1:0: [sdb] CDB: Read(10) 28 00 00 00 00 04 00 00 02 00
[  502.101279] blk_update_request: I/O error, dev sdb, sector 4
[  502.101495] Buffer I/O error on dev sdb, logical block 2, async page read
[  600.128255] INFO: task kworker/u2:2:60 blocked for more than 120 seconds.
[  600.128486]       Not tainted 4.3.0-rc1+ #74
[  600.128687] "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message.
[  600.128891] kworker/u2:2    D 00000040     0    60      2 0x00000000
[  600.129381] Workqueue: events_unbound async_run_entry_fn
[  600.129709]  cf9e8780 00000046 2eff25f7 00000040 c117f111 2ee82733 00000040 0016fec4
[  600.130941]  00000000 cfaa6000 00000000 7fffffff c139c7d2 c139c504 7fffffff c139d9d3
[  600.132342]  00000040 cfaa5cfc c106f460 00161108 00000000 0000c648 2106dcce 00000040
[  600.133613] Call Trace:
[  600.133821]  [<c117f111>] ? blk_queue_bio+0x1e8/0x1fb
[  600.134065]  [<c139c7d2>] ? bit_wait_io_timeout+0x3d/0x3d
[  600.134283]  [<c139c504>] ? schedule+0x5b/0x67
[  600.134509]  [<c139d9d3>] ? schedule_timeout+0x13/0xc5
[  600.134723]  [<c106f460>] ? timekeeping_get_ns+0x10/0x69
[  600.134948]  [<c139c7d2>] ? bit_wait_io_timeout+0x3d/0x3d
[  600.135154]  [<c106fae7>] ? ktime_get+0x38/0x48
[  600.135377]  [<c139bf83>] ? io_schedule_timeout+0x83/0xd7
[  600.135576]  [<c139c7f3>] ? bit_wait_io+0x21/0x26
[  600.135788]  [<c139c697>] ? __wait_on_bit+0x2f/0x5a
[  600.136000]  [<c10ff1eb>] ? blkdev_readpages+0x15/0x15
[  600.136399]  [<c10ad361>] ? wait_on_page_bit+0x57/0x5e
[  600.136607]  [<c1054a98>] ? wake_atomic_t_function+0x2a/0x2a
[  600.136838]  [<c10ad386>] ? wait_on_page_read+0xf/0x2a
[  600.137044]  [<c10ae0e1>] ? do_read_cache_page+0x8e/0x116
[  600.137276]  [<c10ff1eb>] ? blkdev_readpages+0x15/0x15
[  600.137481]  [<c10ae192>] ? read_cache_page+0x14/0x18
[  600.137699]  [<c1189b0e>] ? read_dev_sector+0x25/0x57
[  600.137901]  [<c118a8a8>] ? adfspart_check_ICS+0x30/0x1ac
[  600.138131]  [<c119a3f1>] ? vsnprintf+0x78/0x25d
[  600.138329]  [<c119a614>] ? snprintf+0x16/0x18
[  600.138544]  [<c118a7ea>] ? check_partition+0xd7/0x165
[  600.138738]  [<c118a067>] ? rescan_partitions+0x95/0x283
[  600.138962]  [<c1254b50>] ? scsi_block_when_processing_errors+0x13/0xae
[  600.139189]  [<c139cbc6>] ? mutex_lock+0x9/0x21
[  600.139427]  [<c1100046>] ? __blkdev_get+0x155/0x2f6
[  600.139632]  [<c110032f>] ? blkdev_get+0x148/0x258
[  600.139865]  [<c10ec747>] ? unlock_new_inode+0x36/0x3c
[  600.140263]  [<c10ff106>] ? bdget+0xdc/0xe6
[  600.140448]  [<c118854f>] ? add_disk+0x221/0x368
[  600.140689]  [<c126321a>] ? sd_probe_async+0xed/0x157
[  600.140908]  [<c10443a0>] ? async_run_entry_fn+0x2c/0xad
[  600.141133]  [<c103f060>] ? process_one_work+0x130/0x21f
[  600.141336]  [<c103f2f6>] ? worker_thread+0x18a/0x247
[  600.141552]  [<c103f16c>] ? process_scheduled_works+0x1d/0x1d
[  600.141764]  [<c1042c46>] ? kthread+0x7c/0x81
[  600.141982]  [<c139e201>] ? ret_from_kernel_thread+0x21/0x30
[  600.142186]  [<c1042bca>] ? kthread_parkme+0x11/0x11
[  600.142426] INFO: task modprobe:1977 blocked for more than 120 seconds.
[  600.142612]       Not tainted 4.3.0-rc1+ #74
[  600.142787] "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message.
[  600.142991] modprobe        D 00000040     0  1977   1969 0x00000000
[  600.143444]  cfb20000 00000086 29042653 00000040 c1525f88 28a83a17 00000040 005bec3c
[  600.144819]  00000000 ccdd0000 ffffffff ffffffff d2057280 c139c504 00000000 c104416d
[  600.146052]  00000000 cfb20000 c1054a45 c151fd8c c151fd8c d2057280 00000000 ccd621f0
[  600.147279] Call Trace:
[  600.147489]  [<c139c504>] ? schedule+0x5b/0x67
[  600.147729]  [<c104416d>] ? async_synchronize_cookie_domain+0x73/0x9f
[  600.147992]  [<c1054a45>] ? abort_exclusive_wait+0x6e/0x6e
[  600.148390]  [<c10ac9bc>] ? do_init_module+0xa4/0x1a3
[  600.148627]  [<c107ddb5>] ? load_module+0x14de/0x18ca
[  600.148846]  [<c107e2a0>] ? SyS_finit_module+0x47/0x56
[  600.149073]  [<c139e2c0>] ? sysenter_do_call+0x12/0x12
[  662.100333] sd 2:0:1:0: [sdb] FAILED Result: hostbyte=DID_TIME_OUT driverbyte=DRIVER_SENSE
[  662.100598] sd 2:0:1:0: [sdb] Sense Key : Aborted Command [current]
[  662.100838] sd 2:0:1:0: [sdb] Add. Sense: No additional sense information
[  662.101076] sd 2:0:1:0: [sdb] CDB: Read(10) 28 00 00 00 00 06 00 00 02 00
[  662.101297] blk_update_request: I/O error, dev sdb, sector 6
[  662.101512] Buffer I/O error on dev sdb, logical block 3, async page read
[  720.148270] INFO: task modprobe:1977 blocked for more than 120 seconds.
[  720.148499]       Not tainted 4.3.0-rc1+ #74
[  720.148699] "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message.
[  720.148903] modprobe        D 00000040     0  1977   1969 0x00000000
[  720.149360]  cfb20000 00000086 29042653 00000040 c1525f88 28a83a17 00000040 005bec3c
[  720.150615]  00000000 ccdd0000 ffffffff ffffffff d2057280 c139c504 00000000 c104416d
[  720.151836]  00000000 cfb20000 c1054a45 c151fd8c c151fd8c d2057280 00000000 ccd621f0
[  720.153221] Call Trace:
[  720.153465]  [<c139c504>] ? schedule+0x5b/0x67
[  720.153689]  [<c104416d>] ? async_synchronize_cookie_domain+0x73/0x9f
[  720.153931]  [<c1054a45>] ? abort_exclusive_wait+0x6e/0x6e
[  720.154149]  [<c10ac9bc>] ? do_init_module+0xa4/0x1a3
[  720.154379]  [<c107ddb5>] ? load_module+0x14de/0x18ca
[  720.154593]  [<c107e2a0>] ? SyS_finit_module+0x47/0x56
[  720.154820]  [<c139e2c0>] ? sysenter_do_call+0x12/0x12
[  781.025039] systemd-logind[1942]: New session c2 of user rainbow.
[  840.152254] INFO: task kworker/u2:2:60 blocked for more than 120 seconds.
[  840.152486]       Not tainted 4.3.0-rc1+ #74
[  840.152693] "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message.
[  840.152903] kworker/u2:2    D 0000009a     0    60      2 0x00000000
[  840.153399] Workqueue: events_unbound async_run_entry_fn
[  840.153730]  cf9e8780 00000046 2860b1ff 0000009a c117f111 284404dd 0000009a 001cad22
[  840.156408]  00000000 cfaa6000 00000000 7fffffff c139c7d2 c139c504 7fffffff c139d9d3
[  840.157689]  0000009a cfaa5c64 c106f460 00161e18 00000000 00013d94 006b70ce 0000009a
[  840.158925] Call Trace:
[  840.159158]  [<c117f111>] ? blk_queue_bio+0x1e8/0x1fb
[  840.159379]  [<c139c7d2>] ? bit_wait_io_timeout+0x3d/0x3d
[  840.159600]  [<c139c504>] ? schedule+0x5b/0x67
[  840.159834]  [<c139d9d3>] ? schedule_timeout+0x13/0xc5
[  840.160052]  [<c106f460>] ? timekeeping_get_ns+0x10/0x69
[  840.160446]  [<c139c7d2>] ? bit_wait_io_timeout+0x3d/0x3d
[  840.160677]  [<c106fae7>] ? ktime_get+0x38/0x48
[  840.160884]  [<c139bf83>] ? io_schedule_timeout+0x83/0xd7
[  840.161105]  [<c139c7f3>] ? bit_wait_io+0x21/0x26
[  840.161306]  [<c139c697>] ? __wait_on_bit+0x2f/0x5a
[  840.161541]  [<c10ad361>] ? wait_on_page_bit+0x57/0x5e
[  840.161767]  [<c1054a98>] ? wake_atomic_t_function+0x2a/0x2a
[  840.161997]  [<c10ad386>] ? wait_on_page_read+0xf/0x2a
[  840.162206]  [<c10ae14f>] ? do_read_cache_page+0xfc/0x116
[  840.162445]  [<c10ff1eb>] ? blkdev_readpages+0x15/0x15
[  840.162651]  [<c10ae192>] ? read_cache_page+0x14/0x18
[  840.162872]  [<c1189b0e>] ? read_dev_sector+0x25/0x57
[  840.163073]  [<c118e22f>] ? read_lba+0x94/0x10b
[  840.163289]  [<c118e7eb>] ? efi_partition+0xbc/0x451
[  840.163506]  [<c10b5c33>] ? put_page+0x16/0x24
[  840.163732]  [<c10ad39d>] ? wait_on_page_read+0x26/0x2a
[  840.163968]  [<c10ff1eb>] ? blkdev_readpages+0x15/0x15
[  840.164348]  [<c10ae192>] ? read_cache_page+0x14/0x18
[  840.164541]  [<c118a8a8>] ? adfspart_check_ICS+0x30/0x1ac
[  840.164777]  [<c119a3f1>] ? vsnprintf+0x78/0x25d
[  840.164977]  [<c119a614>] ? snprintf+0x16/0x18
[  840.165187]  [<c118a7ea>] ? check_partition+0xd7/0x165
[  840.165382]  [<c118a067>] ? rescan_partitions+0x95/0x283
[  840.165603]  [<c1254b50>] ? scsi_block_when_processing_errors+0x13/0xae
[  840.165829]  [<c139cbc6>] ? mutex_lock+0x9/0x21
[  840.166066]  [<c1100046>] ? __blkdev_get+0x155/0x2f6
[  840.166270]  [<c110032f>] ? blkdev_get+0x148/0x258
[  840.166501]  [<c10ec747>] ? unlock_new_inode+0x36/0x3c
[  840.166707]  [<c10ff106>] ? bdget+0xdc/0xe6
[  840.166914]  [<c118854f>] ? add_disk+0x221/0x368
[  840.167134]  [<c126321a>] ? sd_probe_async+0xed/0x157
[  840.167372]  [<c10443a0>] ? async_run_entry_fn+0x2c/0xad
[  840.167582]  [<c103f060>] ? process_one_work+0x130/0x21f
[  840.167802]  [<c103f2f6>] ? worker_thread+0x18a/0x247
[  840.168006]  [<c103f16c>] ? process_scheduled_works+0x1d/0x1d
[  840.168416]  [<c1042c46>] ? kthread+0x7c/0x81
[  840.168642]  [<c139e201>] ? ret_from_kernel_thread+0x21/0x30
[  840.168847]  [<c1042bca>] ? kthread_parkme+0x11/0x11
[  840.169094] INFO: task modprobe:1977 blocked for more than 120 seconds.
[  840.169281]       Not tainted 4.3.0-rc1+ #74
[  840.169454] "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message.
[  840.169659] modprobe        D 00000040     0  1977   1969 0x00000000
[  840.170114]  cfb20000 00000086 29042653 00000040 c1525f88 28a83a17 00000040 005bec3c
[  840.171368]  00000000 ccdd0000 ffffffff ffffffff d2057280 c139c504 00000000 c104416d
[  840.172741]  00000000 cfb20000 c1054a45 c151fd8c c151fd8c d2057280 00000000 ccd621f0
[  840.173986] Call Trace:
[  840.174200]  [<c139c504>] ? schedule+0x5b/0x67
[  840.174443]  [<c104416d>] ? async_synchronize_cookie_domain+0x73/0x9f
[  840.174689]  [<c1054a45>] ? abort_exclusive_wait+0x6e/0x6e
[  840.174910]  [<c10ac9bc>] ? do_init_module+0xa4/0x1a3
[  840.175141]  [<c107ddb5>] ? load_module+0x14de/0x18ca
[  840.175359]  [<c107e2a0>] ? SyS_finit_module+0x47/0x56
[  840.175607]  [<c139e2c0>] ? sysenter_do_call+0x12/0x12
[  856.020359] sd 2:0:1:0: [sdb] FAILED Result: hostbyte=DID_TIME_OUT driverbyte=DRIVER_SENSE
[  856.020623] sd 2:0:1:0: [sdb] Sense Key : Aborted Command [current]
[  856.020862] sd 2:0:1:0: [sdb] Add. Sense: No additional sense information
[  856.021101] sd 2:0:1:0: [sdb] CDB: Read(10) 28 00 00 00 00 02 00 00 02 00
[  856.021324] blk_update_request: I/O error, dev sdb, sector 2
[  856.021539] Buffer I/O error on dev sdb, logical block 1, async page read
[  857.025325] sd 2:0:1:0: [sdb] FAILED Result: hostbyte=DID_ABORT driverbyte=DRIVER_OK
[  857.025596] sd 2:0:1:0: [sdb] CDB: Read(10) 28 00 00 00 00 04 00 00 02 00
[  857.025830] blk_update_request: I/O error, dev sdb, sector 4
[  857.026043] Buffer I/O error on dev sdb, logical block 2, async page read
                             
                             
And a CD-ROM, first without patches:
[  655.929795] pnp 01:01.00: activated
[  655.939503] scsi host2: Generic NCR5380/NCR53C400 SCSI, io_port 0x240, n_io_port 16, base 0x0, irq 0, can_queue 16, cmd_per_lun 2, sg_tablesize 128, this_id 7, flags { DTC3181E NO_PSEUDO_DMA }, USLEEP_POLL 3, USLEEP_WAITLONG 1250, options { AUTOPROBE_IRQ PSEUDO_DMA NCR53C400 }
[  656.441943] scsi 2:0:2:0: CD-ROM            SONY     CD-ROM CDU-55S   1.0t PQ: 0 ANSI: 2
[  657.829087] scsi 2:0:2:0: Attached scsi generic sg1 type 5
[  658.325517] sr 2:0:2:0: [sr0] scsi-1 drive
[  658.325731] cdrom: Uniform CD-ROM driver Revision: 3.20

Modprobe succeeded but mount resulted in this & hang:
[  694.056266] sr 2:0:2:0: [sr0] aborting command

Then with patches:

[  109.753273] pnp 01:01.00: activated
[  109.763039] scsi host2: Generic NCR5380/NCR53C400 SCSI, io_port 0x240, n_io_port 16, base 0x0, irq 0, can_queue 16, cmd_per_lun 2, sg_tablesize 128, this_id 7, flags { DTC3181E NO_PSEUDO_DMA }, options { AUTOPROBE_IRQ PSEUDO_DMA }
[  115.456294] scsi 2:0:2:0: CD-ROM            SONY     CD-ROM CDU-55S   1.0t PQ: 0 ANSI: 2
[  126.823400] scsi 2:0:2:0: Attached scsi generic sg1 type 5
[  126.909680] sr 2:0:2:0: [sr0] scsi-1 drive
[  126.909888] cdrom: Uniform CD-ROM driver Revision: 3.20

Modprobe succeeded but mount failed after some time with this:
[ 1005.149546] sr 2:0:2:0: [sr0] FAILED Result: hostbyte=DID_OK driverbyte=DRIVER_SENSE
[ 1005.149764] sr 2:0:2:0: [sr0] Sense Key : Illegal Request [current]
[ 1005.149992] sr 2:0:2:0: [sr0] Add. Sense: Logical block address out of range
[ 1005.150222] sr 2:0:2:0: [sr0] CDB: Read(10) 28 00 00 05 7a 94 00 00 02 00
[ 1005.150433] blk_update_request: critical target error, dev sr0, sector 1436240
[ 1005.154101] sr 2:0:2:0: [sr0] FAILED Result: hostbyte=DID_OK driverbyte=DRIVER_SENSE
[ 1005.154309] sr 2:0:2:0: [sr0] Sense Key : Illegal Request [current]
[ 1005.154533] sr 2:0:2:0: [sr0] Add. Sense: Logical block address out of range
[ 1005.156209] sr 2:0:2:0: [sr0] CDB: Read(10) 28 00 00 05 7a 94 00 00 02 00
[ 1005.156404] blk_update_request: critical target error, dev sr0, sector 1436240
[ 1005.156607] Buffer I/O error on dev sr0, logical block 179530, async page read

mount: unknown filesystem type 'iso9660'

-- 
Ondrej Zary

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

* Re: [PATCH 00/71] More fixes, cleanup and modernization for NCR5380 drivers
  2015-11-20 18:29         ` Ondrej Zary
@ 2015-11-21  1:58           ` Finn Thain
  2015-11-21 13:01             ` Ondrej Zary
  0 siblings, 1 reply; 268+ messages in thread
From: Finn Thain @ 2015-11-21  1:58 UTC (permalink / raw)
  To: Ondrej Zary
  Cc: Sam Creasey, Michael Schmitz, James E.J. Bottomley, linux-m68k,
	linux-scsi, linux-kernel


Hi Ondrej,

On Fri, 20 Nov 2015, Ondrej Zary wrote:

> On Friday 20 November 2015 02:41:19 Finn Thain wrote:
> > 
> > 
> > My tests involved 3 different scsi targets (two disks and a CD-ROM) 
> > but none of these send a SDTR. Your log says the driver correctly 
> > rejected the SDTR message but that doesn't mean the target actually 
> > went to MSG IN phase and got the message. Do you have any older 
> > targets you can test?
> 
> Another disk, without patches:
> 
> [   84.481582] pnp 01:01.00: activated
> [   84.489650] scsi host2: Generic NCR5380/NCR53C400 SCSI, io_port 0x240, n_io_port 16, base 0x0, irq 0, can_queue 16, cmd_per_lun 2, sg_tablesize 128, this_id 7, flags { DTC3181E NO_PSEUDO_DMA }, USLEEP_POLL 3, USLEEP_WAITLONG 1250, options { AUTOPROBE_IRQ PSEUDO_DMA NCR53C400 }
> [   84.953332] scsi 2:0:1:0: Direct-Access     QUANTUM  LP240S GM240S01X 4.6  PQ: 0 ANSI: 2 CCS
> [   86.786475] sd 2:0:1:0: Attached scsi generic sg1 type 0
> [   86.793753] sd 2:0:1:0: [sdb] 479350 512-byte logical blocks: (245 MB/234 MiB)
> [   86.998555] sd 2:0:1:0: [sdb] Write Protect is off
> [   87.406068] sd 2:0:1:0: [sdb] Write cache: enabled, read cache: enabled, doesn't support DPO or FUA
> [  118.888271] sd 2:0:1:0: [sdb] aborting command
> [  118.888738] sd 2:0:1:0: [sdb] aborting command
> 
> With patches:
> 
> [  258.473748] pnp 01:01.00: activated
> [  258.483592] scsi host2: Generic NCR5380/NCR53C400 SCSI, io_port 0x240, n_io_port 16, base 0x0, irq 0, can_queue 16, cmd_per_lun 2, sg_tablesize 128, this_id 7, flags { DTC3181E NO_PSEUDO_DMA }, options { AUTOPROBE_IRQ PSEUDO_DMA }
> [  261.347632] scsi 2:0:1:0: Direct-Access     QUANTUM  LP240S GM240S01X 4.6  PQ: 0 ANSI: 2 CCS
> [  275.560451] sd 2:0:1:0: Attached scsi generic sg1 type 0
> [  275.632519] sd 2:0:1:0: [sdb] 479350 512-byte logical blocks: (245 MB/234 MiB)
> [  275.635533] sd 2:0:1:0: [sdb] Write Protect is off
> [  275.642315] sd 2:0:1:0: [sdb] Write cache: enabled, read cache: enabled, doesn't support DPO or FUA
> [  469.076347] sd 2:0:1:0: [sdb] FAILED Result: hostbyte=DID_TIME_OUT driverbyte=DRIVER_SENSE
> [  469.076613] sd 2:0:1:0: [sdb] Sense Key : Aborted Command [current]
> [  469.076851] sd 2:0:1:0: [sdb] Add. Sense: No additional sense information
> [  469.077086] sd 2:0:1:0: [sdb] CDB: Read(10) 28 00 00 00 00 02 00 00 02 00
> [  469.077306] blk_update_request: I/O error, dev sdb, sector 2
> [  469.077522] Buffer I/O error on dev sdb, logical block 1, async page read
> [  480.108255] INFO: task kworker/u2:2:60 blocked for more than 120 seconds.
> [  480.109773]       Not tainted 4.3.0-rc1+ #74
> [  480.109973] "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message.
> [  480.110179] kworker/u2:2    D 00000040     0    60      2 0x00000000
> [  480.110671] Workqueue: events_unbound async_run_entry_fn
> [  480.110999]  cf9e8780 00000046 2eff25f7 00000040 c117f111 2ee82733 00000040 0016fec4
> [  480.112390]  00000000 cfaa6000 00000000 7fffffff c139c7d2 c139c504 7fffffff c139d9d3
> [  480.113661]  00000040 cfaa5cfc c106f460 00161108 00000000 0000c648 2106dcce 00000040
> [  480.114893] Call Trace:
> [  480.115124]  [<c117f111>] ? blk_queue_bio+0x1e8/0x1fb
> [  480.115344]  [<c139c7d2>] ? bit_wait_io_timeout+0x3d/0x3d
> [  480.115564]  [<c139c504>] ? schedule+0x5b/0x67
> [  480.115794]  [<c139d9d3>] ? schedule_timeout+0x13/0xc5
> [  480.116007]  [<c106f460>] ? timekeeping_get_ns+0x10/0x69
> [  480.116406]  [<c139c7d2>] ? bit_wait_io_timeout+0x3d/0x3d
> [  480.116636]  [<c106fae7>] ? ktime_get+0x38/0x48
> [  480.116843]  [<c139bf83>] ? io_schedule_timeout+0x83/0xd7
> [  480.117062]  [<c139c7f3>] ? bit_wait_io+0x21/0x26
> [  480.117256]  [<c139c697>] ? __wait_on_bit+0x2f/0x5a
> [  480.117486]  [<c10ff1eb>] ? blkdev_readpages+0x15/0x15
> [  480.117704]  [<c10ad361>] ? wait_on_page_bit+0x57/0x5e
> [  480.117942]  [<c1054a98>] ? wake_atomic_t_function+0x2a/0x2a
> [  480.118151]  [<c10ad386>] ? wait_on_page_read+0xf/0x2a
> [  480.118373]  [<c10ae0e1>] ? do_read_cache_page+0x8e/0x116
> [  480.118587]  [<c10ff1eb>] ? blkdev_readpages+0x15/0x15
> [  480.118809]  [<c10ae192>] ? read_cache_page+0x14/0x18
> [  480.119008]  [<c1189b0e>] ? read_dev_sector+0x25/0x57
> [  480.119222]  [<c118a8a8>] ? adfspart_check_ICS+0x30/0x1ac
> [  480.119438]  [<c119a3f1>] ? vsnprintf+0x78/0x25d
> [  480.119671]  [<c119a614>] ? snprintf+0x16/0x18
> [  480.119874]  [<c118a7ea>] ? check_partition+0xd7/0x165
> [  480.120253]  [<c118a067>] ? rescan_partitions+0x95/0x283
> [  480.120443]  [<c1254b50>] ? scsi_block_when_processing_errors+0x13/0xae
> [  480.120693]  [<c139cbc6>] ? mutex_lock+0x9/0x21
> [  480.120915]  [<c1100046>] ? __blkdev_get+0x155/0x2f6
> [  480.121133]  [<c110032f>] ? blkdev_get+0x148/0x258
> [  480.121350]  [<c10ec747>] ? unlock_new_inode+0x36/0x3c
> [  480.121570]  [<c10ff106>] ? bdget+0xdc/0xe6
> [  480.121761]  [<c118854f>] ? add_disk+0x221/0x368
> [  480.121996]  [<c126321a>] ? sd_probe_async+0xed/0x157
> [  480.122214]  [<c10443a0>] ? async_run_entry_fn+0x2c/0xad
> [  480.122437]  [<c103f060>] ? process_one_work+0x130/0x21f
> [  480.122639]  [<c103f2f6>] ? worker_thread+0x18a/0x247
> [  480.122854]  [<c103f16c>] ? process_scheduled_works+0x1d/0x1d
> [  480.123069]  [<c1042c46>] ? kthread+0x7c/0x81
> [  480.123288]  [<c139e201>] ? ret_from_kernel_thread+0x21/0x30
> [  480.123493]  [<c1042bca>] ? kthread_parkme+0x11/0x11
> [  480.123733] INFO: task modprobe:1977 blocked for more than 120 seconds.
> [  480.123919]       Not tainted 4.3.0-rc1+ #74
> [  480.124239] "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message.
> [  480.124410] modprobe        D 00000040     0  1977   1969 0x00000000
> [  480.124864]  cfb20000 00000086 29042653 00000040 c1525f88 28a83a17 00000040 005bec3c
> [  480.126123]  00000000 ccdd0000 ffffffff ffffffff d2057280 c139c504 00000000 c104416d
> [  480.127354]  00000000 cfb20000 c1054a45 c151fd8c c151fd8c d2057280 00000000 ccd621f0
> [  480.128746] Call Trace:
> [  480.128961]  [<c139c504>] ? schedule+0x5b/0x67
> [  480.129202]  [<c104416d>] ? async_synchronize_cookie_domain+0x73/0x9f
> [  480.129449]  [<c1054a45>] ? abort_exclusive_wait+0x6e/0x6e
> [  480.129667]  [<c10ac9bc>] ? do_init_module+0xa4/0x1a3
> [  480.129899]  [<c107ddb5>] ? load_module+0x14de/0x18ca
> [  480.130119]  [<c107e2a0>] ? SyS_finit_module+0x47/0x56
> [  480.130346]  [<c139e2c0>] ? sysenter_do_call+0x12/0x12
> [  502.100317] sd 2:0:1:0: [sdb] FAILED Result: hostbyte=DID_TIME_OUT driverbyte=DRIVER_SENSE
> [  502.100578] sd 2:0:1:0: [sdb] Sense Key : Aborted Command [current]
> [  502.100818] sd 2:0:1:0: [sdb] Add. Sense: No additional sense information
> [  502.101057] sd 2:0:1:0: [sdb] CDB: Read(10) 28 00 00 00 00 04 00 00 02 00
> [  502.101279] blk_update_request: I/O error, dev sdb, sector 4
> [  502.101495] Buffer I/O error on dev sdb, logical block 2, async page read
> [  600.128255] INFO: task kworker/u2:2:60 blocked for more than 120 seconds.
> [  600.128486]       Not tainted 4.3.0-rc1+ #74
> [  600.128687] "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message.
> [  600.128891] kworker/u2:2    D 00000040     0    60      2 0x00000000
> [  600.129381] Workqueue: events_unbound async_run_entry_fn
> [  600.129709]  cf9e8780 00000046 2eff25f7 00000040 c117f111 2ee82733 00000040 0016fec4
> [  600.130941]  00000000 cfaa6000 00000000 7fffffff c139c7d2 c139c504 7fffffff c139d9d3
> [  600.132342]  00000040 cfaa5cfc c106f460 00161108 00000000 0000c648 2106dcce 00000040
> [  600.133613] Call Trace:
> [  600.133821]  [<c117f111>] ? blk_queue_bio+0x1e8/0x1fb
> [  600.134065]  [<c139c7d2>] ? bit_wait_io_timeout+0x3d/0x3d
> [  600.134283]  [<c139c504>] ? schedule+0x5b/0x67
> [  600.134509]  [<c139d9d3>] ? schedule_timeout+0x13/0xc5
> [  600.134723]  [<c106f460>] ? timekeeping_get_ns+0x10/0x69
> [  600.134948]  [<c139c7d2>] ? bit_wait_io_timeout+0x3d/0x3d
> [  600.135154]  [<c106fae7>] ? ktime_get+0x38/0x48
> [  600.135377]  [<c139bf83>] ? io_schedule_timeout+0x83/0xd7
> [  600.135576]  [<c139c7f3>] ? bit_wait_io+0x21/0x26
> [  600.135788]  [<c139c697>] ? __wait_on_bit+0x2f/0x5a
> [  600.136000]  [<c10ff1eb>] ? blkdev_readpages+0x15/0x15
> [  600.136399]  [<c10ad361>] ? wait_on_page_bit+0x57/0x5e
> [  600.136607]  [<c1054a98>] ? wake_atomic_t_function+0x2a/0x2a
> [  600.136838]  [<c10ad386>] ? wait_on_page_read+0xf/0x2a
> [  600.137044]  [<c10ae0e1>] ? do_read_cache_page+0x8e/0x116
> [  600.137276]  [<c10ff1eb>] ? blkdev_readpages+0x15/0x15
> [  600.137481]  [<c10ae192>] ? read_cache_page+0x14/0x18
> [  600.137699]  [<c1189b0e>] ? read_dev_sector+0x25/0x57
> [  600.137901]  [<c118a8a8>] ? adfspart_check_ICS+0x30/0x1ac
> [  600.138131]  [<c119a3f1>] ? vsnprintf+0x78/0x25d
> [  600.138329]  [<c119a614>] ? snprintf+0x16/0x18
> [  600.138544]  [<c118a7ea>] ? check_partition+0xd7/0x165
> [  600.138738]  [<c118a067>] ? rescan_partitions+0x95/0x283
> [  600.138962]  [<c1254b50>] ? scsi_block_when_processing_errors+0x13/0xae
> [  600.139189]  [<c139cbc6>] ? mutex_lock+0x9/0x21
> [  600.139427]  [<c1100046>] ? __blkdev_get+0x155/0x2f6
> [  600.139632]  [<c110032f>] ? blkdev_get+0x148/0x258
> [  600.139865]  [<c10ec747>] ? unlock_new_inode+0x36/0x3c
> [  600.140263]  [<c10ff106>] ? bdget+0xdc/0xe6
> [  600.140448]  [<c118854f>] ? add_disk+0x221/0x368
> [  600.140689]  [<c126321a>] ? sd_probe_async+0xed/0x157
> [  600.140908]  [<c10443a0>] ? async_run_entry_fn+0x2c/0xad
> [  600.141133]  [<c103f060>] ? process_one_work+0x130/0x21f
> [  600.141336]  [<c103f2f6>] ? worker_thread+0x18a/0x247
> [  600.141552]  [<c103f16c>] ? process_scheduled_works+0x1d/0x1d
> [  600.141764]  [<c1042c46>] ? kthread+0x7c/0x81
> [  600.141982]  [<c139e201>] ? ret_from_kernel_thread+0x21/0x30
> [  600.142186]  [<c1042bca>] ? kthread_parkme+0x11/0x11
> [  600.142426] INFO: task modprobe:1977 blocked for more than 120 seconds.
> [  600.142612]       Not tainted 4.3.0-rc1+ #74
> [  600.142787] "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message.
> [  600.142991] modprobe        D 00000040     0  1977   1969 0x00000000
> [  600.143444]  cfb20000 00000086 29042653 00000040 c1525f88 28a83a17 00000040 005bec3c
> [  600.144819]  00000000 ccdd0000 ffffffff ffffffff d2057280 c139c504 00000000 c104416d
> [  600.146052]  00000000 cfb20000 c1054a45 c151fd8c c151fd8c d2057280 00000000 ccd621f0
> [  600.147279] Call Trace:
> [  600.147489]  [<c139c504>] ? schedule+0x5b/0x67
> [  600.147729]  [<c104416d>] ? async_synchronize_cookie_domain+0x73/0x9f
> [  600.147992]  [<c1054a45>] ? abort_exclusive_wait+0x6e/0x6e
> [  600.148390]  [<c10ac9bc>] ? do_init_module+0xa4/0x1a3
> [  600.148627]  [<c107ddb5>] ? load_module+0x14de/0x18ca
> [  600.148846]  [<c107e2a0>] ? SyS_finit_module+0x47/0x56
> [  600.149073]  [<c139e2c0>] ? sysenter_do_call+0x12/0x12
> [  662.100333] sd 2:0:1:0: [sdb] FAILED Result: hostbyte=DID_TIME_OUT driverbyte=DRIVER_SENSE
> [  662.100598] sd 2:0:1:0: [sdb] Sense Key : Aborted Command [current]
> [  662.100838] sd 2:0:1:0: [sdb] Add. Sense: No additional sense information
> [  662.101076] sd 2:0:1:0: [sdb] CDB: Read(10) 28 00 00 00 00 06 00 00 02 00
> [  662.101297] blk_update_request: I/O error, dev sdb, sector 6
> [  662.101512] Buffer I/O error on dev sdb, logical block 3, async page read
> [  720.148270] INFO: task modprobe:1977 blocked for more than 120 seconds.
> [  720.148499]       Not tainted 4.3.0-rc1+ #74
> [  720.148699] "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message.
> [  720.148903] modprobe        D 00000040     0  1977   1969 0x00000000
> [  720.149360]  cfb20000 00000086 29042653 00000040 c1525f88 28a83a17 00000040 005bec3c
> [  720.150615]  00000000 ccdd0000 ffffffff ffffffff d2057280 c139c504 00000000 c104416d
> [  720.151836]  00000000 cfb20000 c1054a45 c151fd8c c151fd8c d2057280 00000000 ccd621f0
> [  720.153221] Call Trace:
> [  720.153465]  [<c139c504>] ? schedule+0x5b/0x67
> [  720.153689]  [<c104416d>] ? async_synchronize_cookie_domain+0x73/0x9f
> [  720.153931]  [<c1054a45>] ? abort_exclusive_wait+0x6e/0x6e
> [  720.154149]  [<c10ac9bc>] ? do_init_module+0xa4/0x1a3
> [  720.154379]  [<c107ddb5>] ? load_module+0x14de/0x18ca
> [  720.154593]  [<c107e2a0>] ? SyS_finit_module+0x47/0x56
> [  720.154820]  [<c139e2c0>] ? sysenter_do_call+0x12/0x12
> [  781.025039] systemd-logind[1942]: New session c2 of user rainbow.
> [  840.152254] INFO: task kworker/u2:2:60 blocked for more than 120 seconds.
> [  840.152486]       Not tainted 4.3.0-rc1+ #74
> [  840.152693] "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message.
> [  840.152903] kworker/u2:2    D 0000009a     0    60      2 0x00000000
> [  840.153399] Workqueue: events_unbound async_run_entry_fn
> [  840.153730]  cf9e8780 00000046 2860b1ff 0000009a c117f111 284404dd 0000009a 001cad22
> [  840.156408]  00000000 cfaa6000 00000000 7fffffff c139c7d2 c139c504 7fffffff c139d9d3
> [  840.157689]  0000009a cfaa5c64 c106f460 00161e18 00000000 00013d94 006b70ce 0000009a
> [  840.158925] Call Trace:
> [  840.159158]  [<c117f111>] ? blk_queue_bio+0x1e8/0x1fb
> [  840.159379]  [<c139c7d2>] ? bit_wait_io_timeout+0x3d/0x3d
> [  840.159600]  [<c139c504>] ? schedule+0x5b/0x67
> [  840.159834]  [<c139d9d3>] ? schedule_timeout+0x13/0xc5
> [  840.160052]  [<c106f460>] ? timekeeping_get_ns+0x10/0x69
> [  840.160446]  [<c139c7d2>] ? bit_wait_io_timeout+0x3d/0x3d
> [  840.160677]  [<c106fae7>] ? ktime_get+0x38/0x48
> [  840.160884]  [<c139bf83>] ? io_schedule_timeout+0x83/0xd7
> [  840.161105]  [<c139c7f3>] ? bit_wait_io+0x21/0x26
> [  840.161306]  [<c139c697>] ? __wait_on_bit+0x2f/0x5a
> [  840.161541]  [<c10ad361>] ? wait_on_page_bit+0x57/0x5e
> [  840.161767]  [<c1054a98>] ? wake_atomic_t_function+0x2a/0x2a
> [  840.161997]  [<c10ad386>] ? wait_on_page_read+0xf/0x2a
> [  840.162206]  [<c10ae14f>] ? do_read_cache_page+0xfc/0x116
> [  840.162445]  [<c10ff1eb>] ? blkdev_readpages+0x15/0x15
> [  840.162651]  [<c10ae192>] ? read_cache_page+0x14/0x18
> [  840.162872]  [<c1189b0e>] ? read_dev_sector+0x25/0x57
> [  840.163073]  [<c118e22f>] ? read_lba+0x94/0x10b
> [  840.163289]  [<c118e7eb>] ? efi_partition+0xbc/0x451
> [  840.163506]  [<c10b5c33>] ? put_page+0x16/0x24
> [  840.163732]  [<c10ad39d>] ? wait_on_page_read+0x26/0x2a
> [  840.163968]  [<c10ff1eb>] ? blkdev_readpages+0x15/0x15
> [  840.164348]  [<c10ae192>] ? read_cache_page+0x14/0x18
> [  840.164541]  [<c118a8a8>] ? adfspart_check_ICS+0x30/0x1ac
> [  840.164777]  [<c119a3f1>] ? vsnprintf+0x78/0x25d
> [  840.164977]  [<c119a614>] ? snprintf+0x16/0x18
> [  840.165187]  [<c118a7ea>] ? check_partition+0xd7/0x165
> [  840.165382]  [<c118a067>] ? rescan_partitions+0x95/0x283
> [  840.165603]  [<c1254b50>] ? scsi_block_when_processing_errors+0x13/0xae
> [  840.165829]  [<c139cbc6>] ? mutex_lock+0x9/0x21
> [  840.166066]  [<c1100046>] ? __blkdev_get+0x155/0x2f6
> [  840.166270]  [<c110032f>] ? blkdev_get+0x148/0x258
> [  840.166501]  [<c10ec747>] ? unlock_new_inode+0x36/0x3c
> [  840.166707]  [<c10ff106>] ? bdget+0xdc/0xe6
> [  840.166914]  [<c118854f>] ? add_disk+0x221/0x368
> [  840.167134]  [<c126321a>] ? sd_probe_async+0xed/0x157
> [  840.167372]  [<c10443a0>] ? async_run_entry_fn+0x2c/0xad
> [  840.167582]  [<c103f060>] ? process_one_work+0x130/0x21f
> [  840.167802]  [<c103f2f6>] ? worker_thread+0x18a/0x247
> [  840.168006]  [<c103f16c>] ? process_scheduled_works+0x1d/0x1d
> [  840.168416]  [<c1042c46>] ? kthread+0x7c/0x81
> [  840.168642]  [<c139e201>] ? ret_from_kernel_thread+0x21/0x30
> [  840.168847]  [<c1042bca>] ? kthread_parkme+0x11/0x11
> [  840.169094] INFO: task modprobe:1977 blocked for more than 120 seconds.
> [  840.169281]       Not tainted 4.3.0-rc1+ #74
> [  840.169454] "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message.
> [  840.169659] modprobe        D 00000040     0  1977   1969 0x00000000
> [  840.170114]  cfb20000 00000086 29042653 00000040 c1525f88 28a83a17 00000040 005bec3c
> [  840.171368]  00000000 ccdd0000 ffffffff ffffffff d2057280 c139c504 00000000 c104416d
> [  840.172741]  00000000 cfb20000 c1054a45 c151fd8c c151fd8c d2057280 00000000 ccd621f0
> [  840.173986] Call Trace:
> [  840.174200]  [<c139c504>] ? schedule+0x5b/0x67
> [  840.174443]  [<c104416d>] ? async_synchronize_cookie_domain+0x73/0x9f
> [  840.174689]  [<c1054a45>] ? abort_exclusive_wait+0x6e/0x6e
> [  840.174910]  [<c10ac9bc>] ? do_init_module+0xa4/0x1a3
> [  840.175141]  [<c107ddb5>] ? load_module+0x14de/0x18ca
> [  840.175359]  [<c107e2a0>] ? SyS_finit_module+0x47/0x56
> [  840.175607]  [<c139e2c0>] ? sysenter_do_call+0x12/0x12
> [  856.020359] sd 2:0:1:0: [sdb] FAILED Result: hostbyte=DID_TIME_OUT driverbyte=DRIVER_SENSE
> [  856.020623] sd 2:0:1:0: [sdb] Sense Key : Aborted Command [current]
> [  856.020862] sd 2:0:1:0: [sdb] Add. Sense: No additional sense information
> [  856.021101] sd 2:0:1:0: [sdb] CDB: Read(10) 28 00 00 00 00 02 00 00 02 00
> [  856.021324] blk_update_request: I/O error, dev sdb, sector 2
> [  856.021539] Buffer I/O error on dev sdb, logical block 1, async page read
> [  857.025325] sd 2:0:1:0: [sdb] FAILED Result: hostbyte=DID_ABORT driverbyte=DRIVER_OK
> [  857.025596] sd 2:0:1:0: [sdb] CDB: Read(10) 28 00 00 00 00 04 00 00 02 00
> [  857.025830] blk_update_request: I/O error, dev sdb, sector 4
> [  857.026043] Buffer I/O error on dev sdb, logical block 2, async page read
>                              
>                              
> And a CD-ROM, first without patches:
> [  655.929795] pnp 01:01.00: activated
> [  655.939503] scsi host2: Generic NCR5380/NCR53C400 SCSI, io_port 0x240, n_io_port 16, base 0x0, irq 0, can_queue 16, cmd_per_lun 2, sg_tablesize 128, this_id 7, flags { DTC3181E NO_PSEUDO_DMA }, USLEEP_POLL 3, USLEEP_WAITLONG 1250, options { AUTOPROBE_IRQ PSEUDO_DMA NCR53C400 }
> [  656.441943] scsi 2:0:2:0: CD-ROM            SONY     CD-ROM CDU-55S   1.0t PQ: 0 ANSI: 2
> [  657.829087] scsi 2:0:2:0: Attached scsi generic sg1 type 5
> [  658.325517] sr 2:0:2:0: [sr0] scsi-1 drive
> [  658.325731] cdrom: Uniform CD-ROM driver Revision: 3.20
> 
> Modprobe succeeded but mount resulted in this & hang:
> [  694.056266] sr 2:0:2:0: [sr0] aborting command
> 
> Then with patches:
> 
> [  109.753273] pnp 01:01.00: activated
> [  109.763039] scsi host2: Generic NCR5380/NCR53C400 SCSI, io_port 0x240, n_io_port 16, base 0x0, irq 0, can_queue 16, cmd_per_lun 2, sg_tablesize 128, this_id 7, flags { DTC3181E NO_PSEUDO_DMA }, options { AUTOPROBE_IRQ PSEUDO_DMA }
> [  115.456294] scsi 2:0:2:0: CD-ROM            SONY     CD-ROM CDU-55S   1.0t PQ: 0 ANSI: 2
> [  126.823400] scsi 2:0:2:0: Attached scsi generic sg1 type 5
> [  126.909680] sr 2:0:2:0: [sr0] scsi-1 drive
> [  126.909888] cdrom: Uniform CD-ROM driver Revision: 3.20
> 
> Modprobe succeeded but mount failed after some time with this:
> [ 1005.149546] sr 2:0:2:0: [sr0] FAILED Result: hostbyte=DID_OK driverbyte=DRIVER_SENSE
> [ 1005.149764] sr 2:0:2:0: [sr0] Sense Key : Illegal Request [current]
> [ 1005.149992] sr 2:0:2:0: [sr0] Add. Sense: Logical block address out of range
> [ 1005.150222] sr 2:0:2:0: [sr0] CDB: Read(10) 28 00 00 05 7a 94 00 00 02 00
> [ 1005.150433] blk_update_request: critical target error, dev sr0, sector 1436240
> [ 1005.154101] sr 2:0:2:0: [sr0] FAILED Result: hostbyte=DID_OK driverbyte=DRIVER_SENSE
> [ 1005.154309] sr 2:0:2:0: [sr0] Sense Key : Illegal Request [current]
> [ 1005.154533] sr 2:0:2:0: [sr0] Add. Sense: Logical block address out of range
> [ 1005.156209] sr 2:0:2:0: [sr0] CDB: Read(10) 28 00 00 05 7a 94 00 00 02 00
> [ 1005.156404] blk_update_request: critical target error, dev sr0, sector 1436240
> [ 1005.156607] Buffer I/O error on dev sr0, logical block 179530, async page read
> 
> mount: unknown filesystem type 'iso9660'
> 
> 

Thanks for these test results! It looks like READ(10) commands don't work. 
I don't know the cause of the failures but it appears to be an old bug. 
Did you find any regression?

I gather that your setup here is a QUANTUM LP240S target with Domex 3181 
(DTC-436) card and g_NCR5380 module. I've been testing a similar setup: 
QUANTUM LPS540S target with a Domex 3191D (DTC-536) card and dmx3191d 
module. In both setups PIO is used exclusively, no IRQ is used, and 
FLAG_DTC3181E is set. I didn't see any issues in my tests, so your results 
are surprising.

Let me know off-list if you want any help to debug this. Unfortunately, 
Domex Technology Corporation in Taiwan never responded to my requests for 
data on the DTC-536 device so there's probably no point in asking them for 
data on the DTC-436 device either.

-- 

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

* Re: [PATCH 00/71] More fixes, cleanup and modernization for NCR5380 drivers
  2015-11-21  1:58           ` Finn Thain
@ 2015-11-21 13:01             ` Ondrej Zary
  2015-11-21 23:07               ` Ondrej Zary
  2015-11-21 23:32               ` Finn Thain
  0 siblings, 2 replies; 268+ messages in thread
From: Ondrej Zary @ 2015-11-21 13:01 UTC (permalink / raw)
  To: Finn Thain
  Cc: Sam Creasey, Michael Schmitz, James E.J. Bottomley, linux-m68k,
	linux-scsi, linux-kernel

On Saturday 21 November 2015 02:58:57 Finn Thain wrote:
> 
> Hi Ondrej,
> 
> On Fri, 20 Nov 2015, Ondrej Zary wrote:
> 
> > On Friday 20 November 2015 02:41:19 Finn Thain wrote:
> > > 
> > > 
> > > My tests involved 3 different scsi targets (two disks and a CD-ROM) 
> > > but none of these send a SDTR. Your log says the driver correctly 
> > > rejected the SDTR message but that doesn't mean the target actually 
> > > went to MSG IN phase and got the message. Do you have any older 
> > > targets you can test?
> > 
> > Another disk, without patches:
> > 
> > [   84.481582] pnp 01:01.00: activated
> > [   84.489650] scsi host2: Generic NCR5380/NCR53C400 SCSI, io_port 0x240, n_io_port 16, base 0x0, irq 0, can_queue 16, cmd_per_lun 2, sg_tablesize 128, this_id 7, flags { DTC3181E NO_PSEUDO_DMA }, USLEEP_POLL 3, USLEEP_WAITLONG 1250, options { AUTOPROBE_IRQ PSEUDO_DMA NCR53C400 }
> > [   84.953332] scsi 2:0:1:0: Direct-Access     QUANTUM  LP240S GM240S01X 4.6  PQ: 0 ANSI: 2 CCS
> > [   86.786475] sd 2:0:1:0: Attached scsi generic sg1 type 0
> > [   86.793753] sd 2:0:1:0: [sdb] 479350 512-byte logical blocks: (245 MB/234 MiB)
> > [   86.998555] sd 2:0:1:0: [sdb] Write Protect is off
> > [   87.406068] sd 2:0:1:0: [sdb] Write cache: enabled, read cache: enabled, doesn't support DPO or FUA
> > [  118.888271] sd 2:0:1:0: [sdb] aborting command
> > [  118.888738] sd 2:0:1:0: [sdb] aborting command
> > 
> > With patches:
> > 
> > [  258.473748] pnp 01:01.00: activated
> > [  258.483592] scsi host2: Generic NCR5380/NCR53C400 SCSI, io_port 0x240, n_io_port 16, base 0x0, irq 0, can_queue 16, cmd_per_lun 2, sg_tablesize 128, this_id 7, flags { DTC3181E NO_PSEUDO_DMA }, options { AUTOPROBE_IRQ PSEUDO_DMA }
> > [  261.347632] scsi 2:0:1:0: Direct-Access     QUANTUM  LP240S GM240S01X 4.6  PQ: 0 ANSI: 2 CCS
> > [  275.560451] sd 2:0:1:0: Attached scsi generic sg1 type 0
> > [  275.632519] sd 2:0:1:0: [sdb] 479350 512-byte logical blocks: (245 MB/234 MiB)
> > [  275.635533] sd 2:0:1:0: [sdb] Write Protect is off
> > [  275.642315] sd 2:0:1:0: [sdb] Write cache: enabled, read cache: enabled, doesn't support DPO or FUA
> > [  469.076347] sd 2:0:1:0: [sdb] FAILED Result: hostbyte=DID_TIME_OUT driverbyte=DRIVER_SENSE
> > [  469.076613] sd 2:0:1:0: [sdb] Sense Key : Aborted Command [current]
> > [  469.076851] sd 2:0:1:0: [sdb] Add. Sense: No additional sense information
> > [  469.077086] sd 2:0:1:0: [sdb] CDB: Read(10) 28 00 00 00 00 02 00 00 02 00
> > [  469.077306] blk_update_request: I/O error, dev sdb, sector 2
> > [  469.077522] Buffer I/O error on dev sdb, logical block 1, async page read
> > [  480.108255] INFO: task kworker/u2:2:60 blocked for more than 120 seconds.
> > [  480.109773]       Not tainted 4.3.0-rc1+ #74
> > [  480.109973] "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message.
> > [  480.110179] kworker/u2:2    D 00000040     0    60      2 0x00000000
> > [  480.110671] Workqueue: events_unbound async_run_entry_fn
> > [  480.110999]  cf9e8780 00000046 2eff25f7 00000040 c117f111 2ee82733 00000040 0016fec4
> > [  480.112390]  00000000 cfaa6000 00000000 7fffffff c139c7d2 c139c504 7fffffff c139d9d3
> > [  480.113661]  00000040 cfaa5cfc c106f460 00161108 00000000 0000c648 2106dcce 00000040
> > [  480.114893] Call Trace:
> > [  480.115124]  [<c117f111>] ? blk_queue_bio+0x1e8/0x1fb
> > [  480.115344]  [<c139c7d2>] ? bit_wait_io_timeout+0x3d/0x3d
> > [  480.115564]  [<c139c504>] ? schedule+0x5b/0x67
> > [  480.115794]  [<c139d9d3>] ? schedule_timeout+0x13/0xc5
> > [  480.116007]  [<c106f460>] ? timekeeping_get_ns+0x10/0x69
> > [  480.116406]  [<c139c7d2>] ? bit_wait_io_timeout+0x3d/0x3d
> > [  480.116636]  [<c106fae7>] ? ktime_get+0x38/0x48
> > [  480.116843]  [<c139bf83>] ? io_schedule_timeout+0x83/0xd7
> > [  480.117062]  [<c139c7f3>] ? bit_wait_io+0x21/0x26
> > [  480.117256]  [<c139c697>] ? __wait_on_bit+0x2f/0x5a
> > [  480.117486]  [<c10ff1eb>] ? blkdev_readpages+0x15/0x15
> > [  480.117704]  [<c10ad361>] ? wait_on_page_bit+0x57/0x5e
> > [  480.117942]  [<c1054a98>] ? wake_atomic_t_function+0x2a/0x2a
> > [  480.118151]  [<c10ad386>] ? wait_on_page_read+0xf/0x2a
> > [  480.118373]  [<c10ae0e1>] ? do_read_cache_page+0x8e/0x116
> > [  480.118587]  [<c10ff1eb>] ? blkdev_readpages+0x15/0x15
> > [  480.118809]  [<c10ae192>] ? read_cache_page+0x14/0x18
> > [  480.119008]  [<c1189b0e>] ? read_dev_sector+0x25/0x57
> > [  480.119222]  [<c118a8a8>] ? adfspart_check_ICS+0x30/0x1ac
> > [  480.119438]  [<c119a3f1>] ? vsnprintf+0x78/0x25d
> > [  480.119671]  [<c119a614>] ? snprintf+0x16/0x18
> > [  480.119874]  [<c118a7ea>] ? check_partition+0xd7/0x165
> > [  480.120253]  [<c118a067>] ? rescan_partitions+0x95/0x283
> > [  480.120443]  [<c1254b50>] ? scsi_block_when_processing_errors+0x13/0xae
> > [  480.120693]  [<c139cbc6>] ? mutex_lock+0x9/0x21
> > [  480.120915]  [<c1100046>] ? __blkdev_get+0x155/0x2f6
> > [  480.121133]  [<c110032f>] ? blkdev_get+0x148/0x258
> > [  480.121350]  [<c10ec747>] ? unlock_new_inode+0x36/0x3c
> > [  480.121570]  [<c10ff106>] ? bdget+0xdc/0xe6
> > [  480.121761]  [<c118854f>] ? add_disk+0x221/0x368
> > [  480.121996]  [<c126321a>] ? sd_probe_async+0xed/0x157
> > [  480.122214]  [<c10443a0>] ? async_run_entry_fn+0x2c/0xad
> > [  480.122437]  [<c103f060>] ? process_one_work+0x130/0x21f
> > [  480.122639]  [<c103f2f6>] ? worker_thread+0x18a/0x247
> > [  480.122854]  [<c103f16c>] ? process_scheduled_works+0x1d/0x1d
> > [  480.123069]  [<c1042c46>] ? kthread+0x7c/0x81
> > [  480.123288]  [<c139e201>] ? ret_from_kernel_thread+0x21/0x30
> > [  480.123493]  [<c1042bca>] ? kthread_parkme+0x11/0x11
> > [  480.123733] INFO: task modprobe:1977 blocked for more than 120 seconds.
> > [  480.123919]       Not tainted 4.3.0-rc1+ #74
> > [  480.124239] "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message.
> > [  480.124410] modprobe        D 00000040     0  1977   1969 0x00000000
> > [  480.124864]  cfb20000 00000086 29042653 00000040 c1525f88 28a83a17 00000040 005bec3c
> > [  480.126123]  00000000 ccdd0000 ffffffff ffffffff d2057280 c139c504 00000000 c104416d
> > [  480.127354]  00000000 cfb20000 c1054a45 c151fd8c c151fd8c d2057280 00000000 ccd621f0
> > [  480.128746] Call Trace:
> > [  480.128961]  [<c139c504>] ? schedule+0x5b/0x67
> > [  480.129202]  [<c104416d>] ? async_synchronize_cookie_domain+0x73/0x9f
> > [  480.129449]  [<c1054a45>] ? abort_exclusive_wait+0x6e/0x6e
> > [  480.129667]  [<c10ac9bc>] ? do_init_module+0xa4/0x1a3
> > [  480.129899]  [<c107ddb5>] ? load_module+0x14de/0x18ca
> > [  480.130119]  [<c107e2a0>] ? SyS_finit_module+0x47/0x56
> > [  480.130346]  [<c139e2c0>] ? sysenter_do_call+0x12/0x12
> > [  502.100317] sd 2:0:1:0: [sdb] FAILED Result: hostbyte=DID_TIME_OUT driverbyte=DRIVER_SENSE
> > [  502.100578] sd 2:0:1:0: [sdb] Sense Key : Aborted Command [current]
> > [  502.100818] sd 2:0:1:0: [sdb] Add. Sense: No additional sense information
> > [  502.101057] sd 2:0:1:0: [sdb] CDB: Read(10) 28 00 00 00 00 04 00 00 02 00
> > [  502.101279] blk_update_request: I/O error, dev sdb, sector 4
> > [  502.101495] Buffer I/O error on dev sdb, logical block 2, async page read
> > [  600.128255] INFO: task kworker/u2:2:60 blocked for more than 120 seconds.
> > [  600.128486]       Not tainted 4.3.0-rc1+ #74
> > [  600.128687] "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message.
> > [  600.128891] kworker/u2:2    D 00000040     0    60      2 0x00000000
> > [  600.129381] Workqueue: events_unbound async_run_entry_fn
> > [  600.129709]  cf9e8780 00000046 2eff25f7 00000040 c117f111 2ee82733 00000040 0016fec4
> > [  600.130941]  00000000 cfaa6000 00000000 7fffffff c139c7d2 c139c504 7fffffff c139d9d3
> > [  600.132342]  00000040 cfaa5cfc c106f460 00161108 00000000 0000c648 2106dcce 00000040
> > [  600.133613] Call Trace:
> > [  600.133821]  [<c117f111>] ? blk_queue_bio+0x1e8/0x1fb
> > [  600.134065]  [<c139c7d2>] ? bit_wait_io_timeout+0x3d/0x3d
> > [  600.134283]  [<c139c504>] ? schedule+0x5b/0x67
> > [  600.134509]  [<c139d9d3>] ? schedule_timeout+0x13/0xc5
> > [  600.134723]  [<c106f460>] ? timekeeping_get_ns+0x10/0x69
> > [  600.134948]  [<c139c7d2>] ? bit_wait_io_timeout+0x3d/0x3d
> > [  600.135154]  [<c106fae7>] ? ktime_get+0x38/0x48
> > [  600.135377]  [<c139bf83>] ? io_schedule_timeout+0x83/0xd7
> > [  600.135576]  [<c139c7f3>] ? bit_wait_io+0x21/0x26
> > [  600.135788]  [<c139c697>] ? __wait_on_bit+0x2f/0x5a
> > [  600.136000]  [<c10ff1eb>] ? blkdev_readpages+0x15/0x15
> > [  600.136399]  [<c10ad361>] ? wait_on_page_bit+0x57/0x5e
> > [  600.136607]  [<c1054a98>] ? wake_atomic_t_function+0x2a/0x2a
> > [  600.136838]  [<c10ad386>] ? wait_on_page_read+0xf/0x2a
> > [  600.137044]  [<c10ae0e1>] ? do_read_cache_page+0x8e/0x116
> > [  600.137276]  [<c10ff1eb>] ? blkdev_readpages+0x15/0x15
> > [  600.137481]  [<c10ae192>] ? read_cache_page+0x14/0x18
> > [  600.137699]  [<c1189b0e>] ? read_dev_sector+0x25/0x57
> > [  600.137901]  [<c118a8a8>] ? adfspart_check_ICS+0x30/0x1ac
> > [  600.138131]  [<c119a3f1>] ? vsnprintf+0x78/0x25d
> > [  600.138329]  [<c119a614>] ? snprintf+0x16/0x18
> > [  600.138544]  [<c118a7ea>] ? check_partition+0xd7/0x165
> > [  600.138738]  [<c118a067>] ? rescan_partitions+0x95/0x283
> > [  600.138962]  [<c1254b50>] ? scsi_block_when_processing_errors+0x13/0xae
> > [  600.139189]  [<c139cbc6>] ? mutex_lock+0x9/0x21
> > [  600.139427]  [<c1100046>] ? __blkdev_get+0x155/0x2f6
> > [  600.139632]  [<c110032f>] ? blkdev_get+0x148/0x258
> > [  600.139865]  [<c10ec747>] ? unlock_new_inode+0x36/0x3c
> > [  600.140263]  [<c10ff106>] ? bdget+0xdc/0xe6
> > [  600.140448]  [<c118854f>] ? add_disk+0x221/0x368
> > [  600.140689]  [<c126321a>] ? sd_probe_async+0xed/0x157
> > [  600.140908]  [<c10443a0>] ? async_run_entry_fn+0x2c/0xad
> > [  600.141133]  [<c103f060>] ? process_one_work+0x130/0x21f
> > [  600.141336]  [<c103f2f6>] ? worker_thread+0x18a/0x247
> > [  600.141552]  [<c103f16c>] ? process_scheduled_works+0x1d/0x1d
> > [  600.141764]  [<c1042c46>] ? kthread+0x7c/0x81
> > [  600.141982]  [<c139e201>] ? ret_from_kernel_thread+0x21/0x30
> > [  600.142186]  [<c1042bca>] ? kthread_parkme+0x11/0x11
> > [  600.142426] INFO: task modprobe:1977 blocked for more than 120 seconds.
> > [  600.142612]       Not tainted 4.3.0-rc1+ #74
> > [  600.142787] "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message.
> > [  600.142991] modprobe        D 00000040     0  1977   1969 0x00000000
> > [  600.143444]  cfb20000 00000086 29042653 00000040 c1525f88 28a83a17 00000040 005bec3c
> > [  600.144819]  00000000 ccdd0000 ffffffff ffffffff d2057280 c139c504 00000000 c104416d
> > [  600.146052]  00000000 cfb20000 c1054a45 c151fd8c c151fd8c d2057280 00000000 ccd621f0
> > [  600.147279] Call Trace:
> > [  600.147489]  [<c139c504>] ? schedule+0x5b/0x67
> > [  600.147729]  [<c104416d>] ? async_synchronize_cookie_domain+0x73/0x9f
> > [  600.147992]  [<c1054a45>] ? abort_exclusive_wait+0x6e/0x6e
> > [  600.148390]  [<c10ac9bc>] ? do_init_module+0xa4/0x1a3
> > [  600.148627]  [<c107ddb5>] ? load_module+0x14de/0x18ca
> > [  600.148846]  [<c107e2a0>] ? SyS_finit_module+0x47/0x56
> > [  600.149073]  [<c139e2c0>] ? sysenter_do_call+0x12/0x12
> > [  662.100333] sd 2:0:1:0: [sdb] FAILED Result: hostbyte=DID_TIME_OUT driverbyte=DRIVER_SENSE
> > [  662.100598] sd 2:0:1:0: [sdb] Sense Key : Aborted Command [current]
> > [  662.100838] sd 2:0:1:0: [sdb] Add. Sense: No additional sense information
> > [  662.101076] sd 2:0:1:0: [sdb] CDB: Read(10) 28 00 00 00 00 06 00 00 02 00
> > [  662.101297] blk_update_request: I/O error, dev sdb, sector 6
> > [  662.101512] Buffer I/O error on dev sdb, logical block 3, async page read
> > [  720.148270] INFO: task modprobe:1977 blocked for more than 120 seconds.
> > [  720.148499]       Not tainted 4.3.0-rc1+ #74
> > [  720.148699] "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message.
> > [  720.148903] modprobe        D 00000040     0  1977   1969 0x00000000
> > [  720.149360]  cfb20000 00000086 29042653 00000040 c1525f88 28a83a17 00000040 005bec3c
> > [  720.150615]  00000000 ccdd0000 ffffffff ffffffff d2057280 c139c504 00000000 c104416d
> > [  720.151836]  00000000 cfb20000 c1054a45 c151fd8c c151fd8c d2057280 00000000 ccd621f0
> > [  720.153221] Call Trace:
> > [  720.153465]  [<c139c504>] ? schedule+0x5b/0x67
> > [  720.153689]  [<c104416d>] ? async_synchronize_cookie_domain+0x73/0x9f
> > [  720.153931]  [<c1054a45>] ? abort_exclusive_wait+0x6e/0x6e
> > [  720.154149]  [<c10ac9bc>] ? do_init_module+0xa4/0x1a3
> > [  720.154379]  [<c107ddb5>] ? load_module+0x14de/0x18ca
> > [  720.154593]  [<c107e2a0>] ? SyS_finit_module+0x47/0x56
> > [  720.154820]  [<c139e2c0>] ? sysenter_do_call+0x12/0x12
> > [  781.025039] systemd-logind[1942]: New session c2 of user rainbow.
> > [  840.152254] INFO: task kworker/u2:2:60 blocked for more than 120 seconds.
> > [  840.152486]       Not tainted 4.3.0-rc1+ #74
> > [  840.152693] "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message.
> > [  840.152903] kworker/u2:2    D 0000009a     0    60      2 0x00000000
> > [  840.153399] Workqueue: events_unbound async_run_entry_fn
> > [  840.153730]  cf9e8780 00000046 2860b1ff 0000009a c117f111 284404dd 0000009a 001cad22
> > [  840.156408]  00000000 cfaa6000 00000000 7fffffff c139c7d2 c139c504 7fffffff c139d9d3
> > [  840.157689]  0000009a cfaa5c64 c106f460 00161e18 00000000 00013d94 006b70ce 0000009a
> > [  840.158925] Call Trace:
> > [  840.159158]  [<c117f111>] ? blk_queue_bio+0x1e8/0x1fb
> > [  840.159379]  [<c139c7d2>] ? bit_wait_io_timeout+0x3d/0x3d
> > [  840.159600]  [<c139c504>] ? schedule+0x5b/0x67
> > [  840.159834]  [<c139d9d3>] ? schedule_timeout+0x13/0xc5
> > [  840.160052]  [<c106f460>] ? timekeeping_get_ns+0x10/0x69
> > [  840.160446]  [<c139c7d2>] ? bit_wait_io_timeout+0x3d/0x3d
> > [  840.160677]  [<c106fae7>] ? ktime_get+0x38/0x48
> > [  840.160884]  [<c139bf83>] ? io_schedule_timeout+0x83/0xd7
> > [  840.161105]  [<c139c7f3>] ? bit_wait_io+0x21/0x26
> > [  840.161306]  [<c139c697>] ? __wait_on_bit+0x2f/0x5a
> > [  840.161541]  [<c10ad361>] ? wait_on_page_bit+0x57/0x5e
> > [  840.161767]  [<c1054a98>] ? wake_atomic_t_function+0x2a/0x2a
> > [  840.161997]  [<c10ad386>] ? wait_on_page_read+0xf/0x2a
> > [  840.162206]  [<c10ae14f>] ? do_read_cache_page+0xfc/0x116
> > [  840.162445]  [<c10ff1eb>] ? blkdev_readpages+0x15/0x15
> > [  840.162651]  [<c10ae192>] ? read_cache_page+0x14/0x18
> > [  840.162872]  [<c1189b0e>] ? read_dev_sector+0x25/0x57
> > [  840.163073]  [<c118e22f>] ? read_lba+0x94/0x10b
> > [  840.163289]  [<c118e7eb>] ? efi_partition+0xbc/0x451
> > [  840.163506]  [<c10b5c33>] ? put_page+0x16/0x24
> > [  840.163732]  [<c10ad39d>] ? wait_on_page_read+0x26/0x2a
> > [  840.163968]  [<c10ff1eb>] ? blkdev_readpages+0x15/0x15
> > [  840.164348]  [<c10ae192>] ? read_cache_page+0x14/0x18
> > [  840.164541]  [<c118a8a8>] ? adfspart_check_ICS+0x30/0x1ac
> > [  840.164777]  [<c119a3f1>] ? vsnprintf+0x78/0x25d
> > [  840.164977]  [<c119a614>] ? snprintf+0x16/0x18
> > [  840.165187]  [<c118a7ea>] ? check_partition+0xd7/0x165
> > [  840.165382]  [<c118a067>] ? rescan_partitions+0x95/0x283
> > [  840.165603]  [<c1254b50>] ? scsi_block_when_processing_errors+0x13/0xae
> > [  840.165829]  [<c139cbc6>] ? mutex_lock+0x9/0x21
> > [  840.166066]  [<c1100046>] ? __blkdev_get+0x155/0x2f6
> > [  840.166270]  [<c110032f>] ? blkdev_get+0x148/0x258
> > [  840.166501]  [<c10ec747>] ? unlock_new_inode+0x36/0x3c
> > [  840.166707]  [<c10ff106>] ? bdget+0xdc/0xe6
> > [  840.166914]  [<c118854f>] ? add_disk+0x221/0x368
> > [  840.167134]  [<c126321a>] ? sd_probe_async+0xed/0x157
> > [  840.167372]  [<c10443a0>] ? async_run_entry_fn+0x2c/0xad
> > [  840.167582]  [<c103f060>] ? process_one_work+0x130/0x21f
> > [  840.167802]  [<c103f2f6>] ? worker_thread+0x18a/0x247
> > [  840.168006]  [<c103f16c>] ? process_scheduled_works+0x1d/0x1d
> > [  840.168416]  [<c1042c46>] ? kthread+0x7c/0x81
> > [  840.168642]  [<c139e201>] ? ret_from_kernel_thread+0x21/0x30
> > [  840.168847]  [<c1042bca>] ? kthread_parkme+0x11/0x11
> > [  840.169094] INFO: task modprobe:1977 blocked for more than 120 seconds.
> > [  840.169281]       Not tainted 4.3.0-rc1+ #74
> > [  840.169454] "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message.
> > [  840.169659] modprobe        D 00000040     0  1977   1969 0x00000000
> > [  840.170114]  cfb20000 00000086 29042653 00000040 c1525f88 28a83a17 00000040 005bec3c
> > [  840.171368]  00000000 ccdd0000 ffffffff ffffffff d2057280 c139c504 00000000 c104416d
> > [  840.172741]  00000000 cfb20000 c1054a45 c151fd8c c151fd8c d2057280 00000000 ccd621f0
> > [  840.173986] Call Trace:
> > [  840.174200]  [<c139c504>] ? schedule+0x5b/0x67
> > [  840.174443]  [<c104416d>] ? async_synchronize_cookie_domain+0x73/0x9f
> > [  840.174689]  [<c1054a45>] ? abort_exclusive_wait+0x6e/0x6e
> > [  840.174910]  [<c10ac9bc>] ? do_init_module+0xa4/0x1a3
> > [  840.175141]  [<c107ddb5>] ? load_module+0x14de/0x18ca
> > [  840.175359]  [<c107e2a0>] ? SyS_finit_module+0x47/0x56
> > [  840.175607]  [<c139e2c0>] ? sysenter_do_call+0x12/0x12
> > [  856.020359] sd 2:0:1:0: [sdb] FAILED Result: hostbyte=DID_TIME_OUT driverbyte=DRIVER_SENSE
> > [  856.020623] sd 2:0:1:0: [sdb] Sense Key : Aborted Command [current]
> > [  856.020862] sd 2:0:1:0: [sdb] Add. Sense: No additional sense information
> > [  856.021101] sd 2:0:1:0: [sdb] CDB: Read(10) 28 00 00 00 00 02 00 00 02 00
> > [  856.021324] blk_update_request: I/O error, dev sdb, sector 2
> > [  856.021539] Buffer I/O error on dev sdb, logical block 1, async page read
> > [  857.025325] sd 2:0:1:0: [sdb] FAILED Result: hostbyte=DID_ABORT driverbyte=DRIVER_OK
> > [  857.025596] sd 2:0:1:0: [sdb] CDB: Read(10) 28 00 00 00 00 04 00 00 02 00
> > [  857.025830] blk_update_request: I/O error, dev sdb, sector 4
> > [  857.026043] Buffer I/O error on dev sdb, logical block 2, async page read
> >                              
> >                              
> > And a CD-ROM, first without patches:
> > [  655.929795] pnp 01:01.00: activated
> > [  655.939503] scsi host2: Generic NCR5380/NCR53C400 SCSI, io_port 0x240, n_io_port 16, base 0x0, irq 0, can_queue 16, cmd_per_lun 2, sg_tablesize 128, this_id 7, flags { DTC3181E NO_PSEUDO_DMA }, USLEEP_POLL 3, USLEEP_WAITLONG 1250, options { AUTOPROBE_IRQ PSEUDO_DMA NCR53C400 }
> > [  656.441943] scsi 2:0:2:0: CD-ROM            SONY     CD-ROM CDU-55S   1.0t PQ: 0 ANSI: 2
> > [  657.829087] scsi 2:0:2:0: Attached scsi generic sg1 type 5
> > [  658.325517] sr 2:0:2:0: [sr0] scsi-1 drive
> > [  658.325731] cdrom: Uniform CD-ROM driver Revision: 3.20
> > 
> > Modprobe succeeded but mount resulted in this & hang:
> > [  694.056266] sr 2:0:2:0: [sr0] aborting command
> > 
> > Then with patches:
> > 
> > [  109.753273] pnp 01:01.00: activated
> > [  109.763039] scsi host2: Generic NCR5380/NCR53C400 SCSI, io_port 0x240, n_io_port 16, base 0x0, irq 0, can_queue 16, cmd_per_lun 2, sg_tablesize 128, this_id 7, flags { DTC3181E NO_PSEUDO_DMA }, options { AUTOPROBE_IRQ PSEUDO_DMA }
> > [  115.456294] scsi 2:0:2:0: CD-ROM            SONY     CD-ROM CDU-55S   1.0t PQ: 0 ANSI: 2
> > [  126.823400] scsi 2:0:2:0: Attached scsi generic sg1 type 5
> > [  126.909680] sr 2:0:2:0: [sr0] scsi-1 drive
> > [  126.909888] cdrom: Uniform CD-ROM driver Revision: 3.20
> > 
> > Modprobe succeeded but mount failed after some time with this:
> > [ 1005.149546] sr 2:0:2:0: [sr0] FAILED Result: hostbyte=DID_OK driverbyte=DRIVER_SENSE
> > [ 1005.149764] sr 2:0:2:0: [sr0] Sense Key : Illegal Request [current]
> > [ 1005.149992] sr 2:0:2:0: [sr0] Add. Sense: Logical block address out of range
> > [ 1005.150222] sr 2:0:2:0: [sr0] CDB: Read(10) 28 00 00 05 7a 94 00 00 02 00
> > [ 1005.150433] blk_update_request: critical target error, dev sr0, sector 1436240
> > [ 1005.154101] sr 2:0:2:0: [sr0] FAILED Result: hostbyte=DID_OK driverbyte=DRIVER_SENSE
> > [ 1005.154309] sr 2:0:2:0: [sr0] Sense Key : Illegal Request [current]
> > [ 1005.154533] sr 2:0:2:0: [sr0] Add. Sense: Logical block address out of range
> > [ 1005.156209] sr 2:0:2:0: [sr0] CDB: Read(10) 28 00 00 05 7a 94 00 00 02 00
> > [ 1005.156404] blk_update_request: critical target error, dev sr0, sector 1436240
> > [ 1005.156607] Buffer I/O error on dev sr0, logical block 179530, async page read
> > 
> > mount: unknown filesystem type 'iso9660'
> > 
> > 
> 
> Thanks for these test results! It looks like READ(10) commands don't work. 
> I don't know the cause of the failures but it appears to be an old bug. 
> Did you find any regression?
> 
> I gather that your setup here is a QUANTUM LP240S target with Domex 3181 
> (DTC-436) card and g_NCR5380 module. I've been testing a similar setup: 
> QUANTUM LPS540S target with a Domex 3191D (DTC-536) card and dmx3191d 
> module. In both setups PIO is used exclusively, no IRQ is used, and 
> FLAG_DTC3181E is set. I didn't see any issues in my tests, so your results 
> are surprising.

I agree that the results are surprising. Even tried 2.4 kernels (Debian 3.1)
and even 2.2 (Debian 3.0) and nothing worked.
HW is fine - the drive is accessible in Windows 98 (with Domex driver
installed).

Now testing the Canon FG2-5202 controller - a simple 8-bit ISA card with only
two chips: NCR 53C400 and 74LS245. It's memory mapped, IRQ hardwired to 7.

# modprobe g_NCR5380_mmio ncr_irq=255 ncr_addr=0xd8000 ncr_53c400=1

[ 1245.919223] scsi2 : interrupts not enabled. for better interactive performance,
[ 1245.919326] scsi2 : please jumper the board for a free IRQ.
[ 1245.919389] scsi host2: Generic NCR5380/NCR53C400 SCSI, io_port 0x0, n_io_port 0, base 0xd8000, irq 0, can_queue 16, cmd_per_lun 2, sg_tablesize 128, this_id 7, flags { NCR53C400 }, USLEEP_POLL 3, USLEEP_WAITLONG 1250, options { AUTOPROBE_IRQ PSEUDO_DMA NCR53C400 }
[ 1246.376738] scsi 2:0:1:0: Direct-Access     QUANTUM  LP240S GM240S01X 4.6  PQ: 0 ANSI: 2 CCS
[ 1248.202198] sd 2:0:1:0: Attached scsi generic sg1 type 0
[ 1248.420856] 53C400r: no 53C80 gated irq after transfer
[ 1248.420948] 53C400r: no end dma signal
[ 1248.422459] sd 2:0:1:0: [sdb] Sector size 0 reported, assuming 512.

Seems that the PSEUDO_DMA is broken. After adding FLAG_NO_PSEUDO_DMA:

# modprobe g_NCR5380_mmio ncr_irq=255 ncr_addr=0xd8000 ncr_53c400=1

[   67.974362] scsi2 : interrupts not enabled. for better interactive performance,
[   67.974463] scsi2 : please jumper the board for a free IRQ.
[   67.974526] scsi host2: Generic NCR5380/NCR53C400 SCSI, io_port 0x0, n_io_port 0, base 0xd8000, irq 0, can_queue 16, cmd_per_lun 2, sg_tablesize 128, this_id 7, flags { NCR53C400 NO_PSEUDO_DMA }, USLEEP_POLL 3, USLEEP_WAITLONG 1250, options { AUTOPROBE_IRQ PSEUDO_DMA NCR53C400 }
[   68.432728] scsi 2:0:1:0: Direct-Access     QUANTUM  LP240S GM240S01X 4.6  PQ: 0 ANSI: 2 CCS
[   70.258258] sd 2:0:1:0: Attached scsi generic sg1 type 0
[   70.277265] sd 2:0:1:0: [sdb] 479350 512-byte logical blocks: (245 MB/234 MiB)
[   70.482252] sd 2:0:1:0: [sdb] Write Protect is off
[   70.482335] sd 2:0:1:0: [sdb] Mode Sense: 8b 00 00 08
[   70.889646] sd 2:0:1:0: [sdb] Write cache: enabled, read cache: enabled, doesn't support DPO or FUA
[   73.159513]  sdb: sdb1
[   74.617099] sd 2:0:1:0: [sdb] Attached SCSI disk

Yeah, first success! I can even mount the filesystem, although it takes ages
(a minute) and these messages:
[  160.872074] sd 2:0:1:0: [sdb] aborting command
[  161.816083] sd 2:0:1:0: [sdb] aborting command

# hdparm -t --direct /dev/sdb

/dev/sdb:
[  244.840075] sd 2:0:1:0: [sdb] aborting command
[  248.824078] sd 2:0:1:0: [sdb] aborting command
[  293.864069] sd 2:0:1:0: [sdb] aborting command
[  297.824075] sd 2:0:1:0: [sdb] aborting command
[  319.765020] blk_update_request: critical target error, dev sdb, sector 0
[  319.972994] blk_update_request: critical target error, dev sdb, sector 0
 Timing O_DIRECT disk reads:   2 MB in 105.26 seconds =  19.46 kB/sec



With your patches (and adding FLAG_NO_PSEUDO_DMA), modprobe is slower but
mount faster (4 seconds) and then works better:

# modprobe g_NCR5380_mmio ncr_irq=255 ncr_addr=0xd8000 ncr_53c400=1

[  130.126185] scsi2 : interrupts not enabled. for better interactive performance,
[  130.126284] scsi2 : please jumper the board for a free IRQ.
[  130.126347] scsi host2: Generic NCR5380/NCR53C400 SCSI, io_port 0x0, n_io_port 0, base 0xd8000, irq 0, can_queue 16, cmd_per_lun 2, sg_tablesize 128, this_id 7, flags { NO_PSEUDO_DMA }, options { AUTOPROBE_IRQ PSEUDO_DMA }
[  145.221755] scsi 2:0:1:0: Direct-Access     QUANTUM  LP240S GM240S01X 4.6  PQ: 0 ANSI: 2 CCS
[  220.629912] sd 2:0:1:0: Attached scsi generic sg1 type 0
[  220.651400] sd 2:0:1:0: [sdb] 479350 512-byte logical blocks: (245 MB/234 MiB)
[  220.654061] sd 2:0:1:0: [sdb] Write Protect is off
[  220.659344] sd 2:0:1:0: [sdb] Write cache: enabled, read cache: enabled, doesn't support DPO or FUA
[  220.732415]  sdb: sdb1
[  220.749760] sd 2:0:1:0: [sdb] Attached SCSI disk

# hdparm -t --direct /dev/sdb

/dev/sdb:
 Timing O_DIRECT disk reads:   2 MB in 18.25 seconds = 112.20 kB/sec



IRQ seems to work too, although driver always shows "irq 0":

# modprobe g_NCR5380_mmio ncr_irq=7 ncr_addr=0xd8000 ncr_53c400=1

[  117.263062] scsi host2: Generic NCR5380/NCR53C400 SCSI, io_port 0x0, n_io_port 0, base 0xd8000, irq 0, can_queue 16, cmd_per_lun 2, sg_tablesize 128, this_id 7, flags { NO_PSEUDO_DMA }, options { AUTOPROBE_IRQ PSEUDO_DMA }
[  132.357474] scsi 2:0:1:0: Direct-Access     QUANTUM  LP240S GM240S01X 4.6  PQ: 0 ANSI: 2 CCS
[  207.765080] sd 2:0:1:0: Attached scsi generic sg1 type 0
[  207.783415] sd 2:0:1:0: [sdb] 479350 512-byte logical blocks: (245 MB/234 MiB)
[  207.786167] sd 2:0:1:0: [sdb] Write Protect is off
[  207.790260] sd 2:0:1:0: [sdb] Write cache: enabled, read cache: enabled, doesn't support DPO or FUA
[  207.859669]  sdb: sdb1
[  207.876556] sd 2:0:1:0: [sdb] Attached SCSI disk

# hdparm -t --direct /dev/sdb

/dev/sdb:
 Timing O_DIRECT disk reads:   2 MB in 18.30 seconds = 111.94 kB/sec

# mount /dev/sdb1 /mnt
# umount /mnt
# head /proc/interrupts
           CPU0
  0:      44793    XT-PIC  timer
  1:          9    XT-PIC  i8042
  2:          0    XT-PIC  cascade
  7:         86    XT-PIC  NCR5380
  8:          1    XT-PIC  rtc0
  9:          0    XT-PIC  uhci_hcd:usb1, uhci_hcd:usb2
 10:       1179    XT-PIC  eth0
 12:        136    XT-PIC  i8042
 14:       3411    XT-PIC  pata_via

-- 
Ondrej Zary

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

* Re: [PATCH 00/71] More fixes, cleanup and modernization for NCR5380 drivers
  2015-11-21 13:01             ` Ondrej Zary
@ 2015-11-21 23:07               ` Ondrej Zary
  2015-11-21 23:32               ` Finn Thain
  1 sibling, 0 replies; 268+ messages in thread
From: Ondrej Zary @ 2015-11-21 23:07 UTC (permalink / raw)
  To: Finn Thain
  Cc: Sam Creasey, Michael Schmitz, James E.J. Bottomley, linux-m68k,
	linux-scsi, linux-kernel

On Saturday 21 November 2015 14:01:39 Ondrej Zary wrote:
> On Saturday 21 November 2015 02:58:57 Finn Thain wrote:
> > 
> > Hi Ondrej,
> > 
> > On Fri, 20 Nov 2015, Ondrej Zary wrote:
> > 
> > > On Friday 20 November 2015 02:41:19 Finn Thain wrote:
> > > > 
> > > > 
> > > > My tests involved 3 different scsi targets (two disks and a CD-ROM) 
> > > > but none of these send a SDTR. Your log says the driver correctly 
> > > > rejected the SDTR message but that doesn't mean the target actually 
> > > > went to MSG IN phase and got the message. Do you have any older 
> > > > targets you can test?
> > > 

[...]

> > > 
> > 
> > Thanks for these test results! It looks like READ(10) commands don't work. 
> > I don't know the cause of the failures but it appears to be an old bug. 
> > Did you find any regression?
> > 
> > I gather that your setup here is a QUANTUM LP240S target with Domex 3181 
> > (DTC-436) card and g_NCR5380 module. I've been testing a similar setup: 
> > QUANTUM LPS540S target with a Domex 3191D (DTC-536) card and dmx3191d 
> > module. In both setups PIO is used exclusively, no IRQ is used, and 
> > FLAG_DTC3181E is set. I didn't see any issues in my tests, so your results 
> > are surprising.
> 
> I agree that the results are surprising. Even tried 2.4 kernels (Debian 3.1)
> and even 2.2 (Debian 3.0) and nothing worked.
> HW is fine - the drive is accessible in Windows 98 (with Domex driver
> installed).
> 
> Now testing the Canon FG2-5202 controller - a simple 8-bit ISA card with only
> two chips: NCR 53C400 and 74LS245. It's memory mapped, IRQ hardwired to 7.
> 
> # modprobe g_NCR5380_mmio ncr_irq=255 ncr_addr=0xd8000 ncr_53c400=1
> 
> [ 1245.919223] scsi2 : interrupts not enabled. for better interactive performance,
> [ 1245.919326] scsi2 : please jumper the board for a free IRQ.
> [ 1245.919389] scsi host2: Generic NCR5380/NCR53C400 SCSI, io_port 0x0, n_io_port 0, base 0xd8000, irq 0, can_queue 16, cmd_per_lun 2, sg_tablesize 128, this_id 7, flags { NCR53C400 }, USLEEP_POLL 3, USLEEP_WAITLONG 1250, options { AUTOPROBE_IRQ PSEUDO_DMA NCR53C400 }
> [ 1246.376738] scsi 2:0:1:0: Direct-Access     QUANTUM  LP240S GM240S01X 4.6  PQ: 0 ANSI: 2 CCS
> [ 1248.202198] sd 2:0:1:0: Attached scsi generic sg1 type 0
> [ 1248.420856] 53C400r: no 53C80 gated irq after transfer
> [ 1248.420948] 53C400r: no end dma signal
> [ 1248.422459] sd 2:0:1:0: [sdb] Sector size 0 reported, assuming 512.
> 
> Seems that the PSEUDO_DMA is broken. After adding FLAG_NO_PSEUDO_DMA:
> 
> # modprobe g_NCR5380_mmio ncr_irq=255 ncr_addr=0xd8000 ncr_53c400=1
> 
> [   67.974362] scsi2 : interrupts not enabled. for better interactive performance,
> [   67.974463] scsi2 : please jumper the board for a free IRQ.
> [   67.974526] scsi host2: Generic NCR5380/NCR53C400 SCSI, io_port 0x0, n_io_port 0, base 0xd8000, irq 0, can_queue 16, cmd_per_lun 2, sg_tablesize 128, this_id 7, flags { NCR53C400 NO_PSEUDO_DMA }, USLEEP_POLL 3, USLEEP_WAITLONG 1250, options { AUTOPROBE_IRQ PSEUDO_DMA NCR53C400 }
> [   68.432728] scsi 2:0:1:0: Direct-Access     QUANTUM  LP240S GM240S01X 4.6  PQ: 0 ANSI: 2 CCS
> [   70.258258] sd 2:0:1:0: Attached scsi generic sg1 type 0
> [   70.277265] sd 2:0:1:0: [sdb] 479350 512-byte logical blocks: (245 MB/234 MiB)
> [   70.482252] sd 2:0:1:0: [sdb] Write Protect is off
> [   70.482335] sd 2:0:1:0: [sdb] Mode Sense: 8b 00 00 08
> [   70.889646] sd 2:0:1:0: [sdb] Write cache: enabled, read cache: enabled, doesn't support DPO or FUA
> [   73.159513]  sdb: sdb1
> [   74.617099] sd 2:0:1:0: [sdb] Attached SCSI disk
> 
> Yeah, first success! I can even mount the filesystem, although it takes ages
> (a minute) and these messages:
> [  160.872074] sd 2:0:1:0: [sdb] aborting command
> [  161.816083] sd 2:0:1:0: [sdb] aborting command
> 
> # hdparm -t --direct /dev/sdb
> 
> /dev/sdb:
> [  244.840075] sd 2:0:1:0: [sdb] aborting command
> [  248.824078] sd 2:0:1:0: [sdb] aborting command
> [  293.864069] sd 2:0:1:0: [sdb] aborting command
> [  297.824075] sd 2:0:1:0: [sdb] aborting command
> [  319.765020] blk_update_request: critical target error, dev sdb, sector 0
> [  319.972994] blk_update_request: critical target error, dev sdb, sector 0
>  Timing O_DIRECT disk reads:   2 MB in 105.26 seconds =  19.46 kB/sec
> 
> 
> 
> With your patches (and adding FLAG_NO_PSEUDO_DMA), modprobe is slower but
> mount faster (4 seconds) and then works better:
> 
> # modprobe g_NCR5380_mmio ncr_irq=255 ncr_addr=0xd8000 ncr_53c400=1
> 
> [  130.126185] scsi2 : interrupts not enabled. for better interactive performance,
> [  130.126284] scsi2 : please jumper the board for a free IRQ.
> [  130.126347] scsi host2: Generic NCR5380/NCR53C400 SCSI, io_port 0x0, n_io_port 0, base 0xd8000, irq 0, can_queue 16, cmd_per_lun 2, sg_tablesize 128, this_id 7, flags { NO_PSEUDO_DMA }, options { AUTOPROBE_IRQ PSEUDO_DMA }
> [  145.221755] scsi 2:0:1:0: Direct-Access     QUANTUM  LP240S GM240S01X 4.6  PQ: 0 ANSI: 2 CCS
> [  220.629912] sd 2:0:1:0: Attached scsi generic sg1 type 0
> [  220.651400] sd 2:0:1:0: [sdb] 479350 512-byte logical blocks: (245 MB/234 MiB)
> [  220.654061] sd 2:0:1:0: [sdb] Write Protect is off
> [  220.659344] sd 2:0:1:0: [sdb] Write cache: enabled, read cache: enabled, doesn't support DPO or FUA
> [  220.732415]  sdb: sdb1
> [  220.749760] sd 2:0:1:0: [sdb] Attached SCSI disk
> 
> # hdparm -t --direct /dev/sdb
> 
> /dev/sdb:
>  Timing O_DIRECT disk reads:   2 MB in 18.25 seconds = 112.20 kB/sec
> 
> 
> 
> IRQ seems to work too, although driver always shows "irq 0":
> 
> # modprobe g_NCR5380_mmio ncr_irq=7 ncr_addr=0xd8000 ncr_53c400=1
> 
> [  117.263062] scsi host2: Generic NCR5380/NCR53C400 SCSI, io_port 0x0, n_io_port 0, base 0xd8000, irq 0, can_queue 16, cmd_per_lun 2, sg_tablesize 128, this_id 7, flags { NO_PSEUDO_DMA }, options { AUTOPROBE_IRQ PSEUDO_DMA }
> [  132.357474] scsi 2:0:1:0: Direct-Access     QUANTUM  LP240S GM240S01X 4.6  PQ: 0 ANSI: 2 CCS
> [  207.765080] sd 2:0:1:0: Attached scsi generic sg1 type 0
> [  207.783415] sd 2:0:1:0: [sdb] 479350 512-byte logical blocks: (245 MB/234 MiB)
> [  207.786167] sd 2:0:1:0: [sdb] Write Protect is off
> [  207.790260] sd 2:0:1:0: [sdb] Write cache: enabled, read cache: enabled, doesn't support DPO or FUA
> [  207.859669]  sdb: sdb1
> [  207.876556] sd 2:0:1:0: [sdb] Attached SCSI disk
> 
> # hdparm -t --direct /dev/sdb
> 
> /dev/sdb:
>  Timing O_DIRECT disk reads:   2 MB in 18.30 seconds = 111.94 kB/sec
> 
> # mount /dev/sdb1 /mnt
> # umount /mnt
> # head /proc/interrupts
>            CPU0
>   0:      44793    XT-PIC  timer
>   1:          9    XT-PIC  i8042
>   2:          0    XT-PIC  cascade
>   7:         86    XT-PIC  NCR5380
>   8:          1    XT-PIC  rtc0
>   9:          0    XT-PIC  uhci_hcd:usb1, uhci_hcd:usb2
>  10:       1179    XT-PIC  eth0
>  12:        136    XT-PIC  i8042
>  14:       3411    XT-PIC  pata_via
> 

Even the HP C2502 (that never worked) works now. It's 8-bit card based on
NCR 53C400A (there are also 74ALS245 and 3 PALCE chips).
Configuration is by using magic numbers, wrote a simple userspace enabler:

#include <stdio.h>
#include <sys/io.h>

const unsigned short io_ports[] = { 0x280, 0x290, 0x300, 0x310, 0x330, 0x340, 0x348, 0x350 };

/* IRQs: 2,3,4,5,7 */
void configure_hp400a(int idx, unsigned char irq) {
        unsigned char b = 0;

        outb(0x0f, 0x779);
        outb(0x22, 0x379);
        outb(0xf0, 0x379);
        outb(0x20, 0x379);
        outb(0x80, 0x379);
        if (irq != 2 && irq != 3 && irq != 4 && irq != 5 && irq != 7)
                irq = 0;
        if (idx >= 0 && idx <= 7)
                b = 0x80 | idx | (irq << 4);
        outb(b, 0x379);
}

int main(void) {
        if (iopl(3)) {
                perror("iopl");
                return 1;
        }

        configure_hp400a(0, 7);

        return 0;
}

And now:
# modprobe g_NCR5380 ncr_irq=255 ncr_addr=0x280 ncr_53c400a=1

[   79.051669] scsi2 : interrupts not enabled. for better interactive performance,
[   79.051770] scsi2 : please jumper the board for a free IRQ.
[   79.051833] scsi host2: Generic NCR5380/NCR53C400 SCSI, io_port 0x280, n_io_port 16, base 0x0, irq 0, can_queue 16, cmd_per_lun 2, sg_tablesize 128, this_id 7, flags { NO_PSEUDO_DMA }, options { AUTOPROBE_IRQ PSEUDO_DMA }
[   95.390329] scsi 2:0:1:0: Direct-Access     QUANTUM  LP240S GM240S01X 4.6  PQ: 0 ANSI: 2 CCS
[  177.022776] sd 2:0:1:0: Attached scsi generic sg1 type 0
[  177.041505] sd 2:0:1:0: [sdb] 479350 512-byte logical blocks: (245 MB/234 MiB)
[  177.044491] sd 2:0:1:0: [sdb] Write Protect is off
[  177.049605] sd 2:0:1:0: [sdb] Write cache: enabled, read cache: enabled, doesn't support DPO or FUA
[  177.129093]  sdb: sdb1
[  177.145439] sd 2:0:1:0: [sdb] Attached SCSI disk

# hdparm -t --direct /dev/sdb

/dev/sdb:
 Timing O_DIRECT disk reads:   2 MB in 21.38 seconds =  95.77 kB/sec

Seems to work without IRQ.
With IRQ is enabled, no interrupts are shown in /proc/interrupts.

-- 
Ondrej Zary

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

* Re: [PATCH 00/71] More fixes, cleanup and modernization for NCR5380 drivers
  2015-11-21 13:01             ` Ondrej Zary
  2015-11-21 23:07               ` Ondrej Zary
@ 2015-11-21 23:32               ` Finn Thain
  2015-11-23 22:55                 ` Ondrej Zary
  1 sibling, 1 reply; 268+ messages in thread
From: Finn Thain @ 2015-11-21 23:32 UTC (permalink / raw)
  To: Ondrej Zary
  Cc: Sam Creasey, Michael Schmitz, James E.J. Bottomley, linux-m68k,
	linux-scsi, linux-kernel


On Sat, 21 Nov 2015, Ondrej Zary wrote:

> On Saturday 21 November 2015 02:58:57 Finn Thain wrote:
> 
> > 
> > I gather that your setup here is a QUANTUM LP240S target with Domex 
> > 3181 (DTC-436) card and g_NCR5380 module. I've been testing a similar 
> > setup: QUANTUM LPS540S target with a Domex 3191D (DTC-536) card and 
> > dmx3191d module. In both setups PIO is used exclusively, no IRQ is 
> > used, and FLAG_DTC3181E is set. I didn't see any issues in my tests, 
> > so your results are surprising.
> 
> I agree that the results are surprising. Even tried 2.4 kernels (Debian 
> 3.1) and even 2.2 (Debian 3.0) and nothing worked. HW is fine - the 
> drive is accessible in Windows 98 (with Domex driver installed).

That's good to know (and very thorough).

> 
> Now testing the Canon FG2-5202 controller - a simple 8-bit ISA card with 
> only two chips: NCR 53C400 and 74LS245. It's memory mapped, IRQ 
> hardwired to 7.
> 
> # modprobe g_NCR5380_mmio ncr_irq=255 ncr_addr=0xd8000 ncr_53c400=1
> 
> [ 1245.919223] scsi2 : interrupts not enabled. for better interactive performance,
> [ 1245.919326] scsi2 : please jumper the board for a free IRQ.
> [ 1245.919389] scsi host2: Generic NCR5380/NCR53C400 SCSI, io_port 0x0, n_io_port 0, base 0xd8000, irq 0, can_queue 16, cmd_per_lun 2, sg_tablesize 128, this_id 7, flags { NCR53C400 }, USLEEP_POLL 3, USLEEP_WAITLONG 1250, options { AUTOPROBE_IRQ PSEUDO_DMA NCR53C400 }
> [ 1246.376738] scsi 2:0:1:0: Direct-Access     QUANTUM  LP240S GM240S01X 4.6  PQ: 0 ANSI: 2 CCS
> [ 1248.202198] sd 2:0:1:0: Attached scsi generic sg1 type 0
> [ 1248.420856] 53C400r: no 53C80 gated irq after transfer
> [ 1248.420948] 53C400r: no end dma signal
> [ 1248.422459] sd 2:0:1:0: [sdb] Sector size 0 reported, assuming 512.
> 
> Seems that the PSEUDO_DMA is broken.

That's been my experience with mac_scsi also (going back 10 years). I'm 
told that it used to work in v2.2. PIO was always usable though hopelessly 
slow.

I haven't yet done any work on the PDMA problem with mac_scsi because 
crashing bugs and the forked core driver seemed to be the more pressing 
problems. And resolving the fork has implications for all of the DMA 
variations anyway.

> After adding FLAG_NO_PSEUDO_DMA:
> 
> # modprobe g_NCR5380_mmio ncr_irq=255 ncr_addr=0xd8000 ncr_53c400=1
> 
> [   67.974362] scsi2 : interrupts not enabled. for better interactive performance,
> [   67.974463] scsi2 : please jumper the board for a free IRQ.
> [   67.974526] scsi host2: Generic NCR5380/NCR53C400 SCSI, io_port 0x0, n_io_port 0, base 0xd8000, irq 0, can_queue 16, cmd_per_lun 2, sg_tablesize 128, this_id 7, flags { NCR53C400 NO_PSEUDO_DMA }, USLEEP_POLL 3, USLEEP_WAITLONG 1250, options { AUTOPROBE_IRQ PSEUDO_DMA NCR53C400 }
> [   68.432728] scsi 2:0:1:0: Direct-Access     QUANTUM  LP240S GM240S01X 4.6  PQ: 0 ANSI: 2 CCS
> [   70.258258] sd 2:0:1:0: Attached scsi generic sg1 type 0
> [   70.277265] sd 2:0:1:0: [sdb] 479350 512-byte logical blocks: (245 MB/234 MiB)
> [   70.482252] sd 2:0:1:0: [sdb] Write Protect is off
> [   70.482335] sd 2:0:1:0: [sdb] Mode Sense: 8b 00 00 08
> [   70.889646] sd 2:0:1:0: [sdb] Write cache: enabled, read cache: enabled, doesn't support DPO or FUA
> [   73.159513]  sdb: sdb1
> [   74.617099] sd 2:0:1:0: [sdb] Attached SCSI disk
> 
> Yeah, first success! I can even mount the filesystem, although it takes ages
> (a minute) and these messages:
> [  160.872074] sd 2:0:1:0: [sdb] aborting command
> [  161.816083] sd 2:0:1:0: [sdb] aborting command
> 
> # hdparm -t --direct /dev/sdb
> 
> /dev/sdb:
> [  244.840075] sd 2:0:1:0: [sdb] aborting command
> [  248.824078] sd 2:0:1:0: [sdb] aborting command
> [  293.864069] sd 2:0:1:0: [sdb] aborting command
> [  297.824075] sd 2:0:1:0: [sdb] aborting command
> [  319.765020] blk_update_request: critical target error, dev sdb, sector 0
> [  319.972994] blk_update_request: critical target error, dev sdb, sector 0
>  Timing O_DIRECT disk reads:   2 MB in 105.26 seconds =  19.46 kB/sec
> 
> 
> 
> With your patches (and adding FLAG_NO_PSEUDO_DMA), modprobe is slower but
> mount faster (4 seconds) and then works better:
> 
> # modprobe g_NCR5380_mmio ncr_irq=255 ncr_addr=0xd8000 ncr_53c400=1
> 
> [  130.126185] scsi2 : interrupts not enabled. for better interactive performance,
> [  130.126284] scsi2 : please jumper the board for a free IRQ.
> [  130.126347] scsi host2: Generic NCR5380/NCR53C400 SCSI, io_port 0x0, n_io_port 0, base 0xd8000, irq 0, can_queue 16, cmd_per_lun 2, sg_tablesize 128, this_id 7, flags { NO_PSEUDO_DMA }, options { AUTOPROBE_IRQ PSEUDO_DMA }
> [  145.221755] scsi 2:0:1:0: Direct-Access     QUANTUM  LP240S GM240S01X 4.6  PQ: 0 ANSI: 2 CCS
> [  220.629912] sd 2:0:1:0: Attached scsi generic sg1 type 0
> [  220.651400] sd 2:0:1:0: [sdb] 479350 512-byte logical blocks: (245 MB/234 MiB)
> [  220.654061] sd 2:0:1:0: [sdb] Write Protect is off
> [  220.659344] sd 2:0:1:0: [sdb] Write cache: enabled, read cache: enabled, doesn't support DPO or FUA
> [  220.732415]  sdb: sdb1
> [  220.749760] sd 2:0:1:0: [sdb] Attached SCSI disk
> 
> # hdparm -t --direct /dev/sdb
> 
> /dev/sdb:
>  Timing O_DIRECT disk reads:   2 MB in 18.25 seconds = 112.20 kB/sec
> 
> 
> 
> IRQ seems to work too, although driver always shows "irq 0":

Your right, there's a superficial bug there that affects the banner in the 
log. But it doesn't affect behaviour (the IRQ should still work). It isn't 
a new bug.

> 
> # modprobe g_NCR5380_mmio ncr_irq=7 ncr_addr=0xd8000 ncr_53c400=1
> 
> [  117.263062] scsi host2: Generic NCR5380/NCR53C400 SCSI, io_port 0x0, n_io_port 0, base 0xd8000, irq 0, can_queue 16, cmd_per_lun 2, sg_tablesize 128, this_id 7, flags { NO_PSEUDO_DMA }, options { AUTOPROBE_IRQ PSEUDO_DMA }
> [  132.357474] scsi 2:0:1:0: Direct-Access     QUANTUM  LP240S GM240S01X 4.6  PQ: 0 ANSI: 2 CCS
> [  207.765080] sd 2:0:1:0: Attached scsi generic sg1 type 0
> [  207.783415] sd 2:0:1:0: [sdb] 479350 512-byte logical blocks: (245 MB/234 MiB)
> [  207.786167] sd 2:0:1:0: [sdb] Write Protect is off
> [  207.790260] sd 2:0:1:0: [sdb] Write cache: enabled, read cache: enabled, doesn't support DPO or FUA
> [  207.859669]  sdb: sdb1
> [  207.876556] sd 2:0:1:0: [sdb] Attached SCSI disk
> 
> # hdparm -t --direct /dev/sdb
> 
> /dev/sdb:
>  Timing O_DIRECT disk reads:   2 MB in 18.30 seconds = 111.94 kB/sec
> 
> # mount /dev/sdb1 /mnt
> # umount /mnt
> # head /proc/interrupts
>            CPU0
>   0:      44793    XT-PIC  timer
>   1:          9    XT-PIC  i8042
>   2:          0    XT-PIC  cascade
>   7:         86    XT-PIC  NCR5380
>   8:          1    XT-PIC  rtc0
>   9:          0    XT-PIC  uhci_hcd:usb1, uhci_hcd:usb2
>  10:       1179    XT-PIC  eth0
>  12:        136    XT-PIC  i8042
>  14:       3411    XT-PIC  pata_via
> 

Nice! Thanks for your perseverance. It is gratifying to see it working.

-- 

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

* Re: [PATCH 00/71] More fixes, cleanup and modernization for NCR5380 drivers
  2015-11-21 23:32               ` Finn Thain
@ 2015-11-23 22:55                 ` Ondrej Zary
  2015-11-24  1:21                   ` Finn Thain
  0 siblings, 1 reply; 268+ messages in thread
From: Ondrej Zary @ 2015-11-23 22:55 UTC (permalink / raw)
  To: Finn Thain
  Cc: Sam Creasey, Michael Schmitz, James E.J. Bottomley, linux-m68k,
	linux-scsi, linux-kernel

On Sunday 22 November 2015 00:32:31 Finn Thain wrote:
> 
> On Sat, 21 Nov 2015, Ondrej Zary wrote:
> 
> > On Saturday 21 November 2015 02:58:57 Finn Thain wrote:
> > 
> > > 
> > > I gather that your setup here is a QUANTUM LP240S target with Domex 
> > > 3181 (DTC-436) card and g_NCR5380 module. I've been testing a similar 
> > > setup: QUANTUM LPS540S target with a Domex 3191D (DTC-536) card and 
> > > dmx3191d module. In both setups PIO is used exclusively, no IRQ is 
> > > used, and FLAG_DTC3181E is set. I didn't see any issues in my tests, 
> > > so your results are surprising.
> > 
> > I agree that the results are surprising. Even tried 2.4 kernels (Debian 
> > 3.1) and even 2.2 (Debian 3.0) and nothing worked. HW is fine - the 
> > drive is accessible in Windows 98 (with Domex driver installed).
> 
> That's good to know (and very thorough).
> 
> > 
> > Now testing the Canon FG2-5202 controller - a simple 8-bit ISA card with 
> > only two chips: NCR 53C400 and 74LS245. It's memory mapped, IRQ 
> > hardwired to 7.
> > 
> > # modprobe g_NCR5380_mmio ncr_irq=255 ncr_addr=0xd8000 ncr_53c400=1
> > 
> > [ 1245.919223] scsi2 : interrupts not enabled. for better interactive performance,
> > [ 1245.919326] scsi2 : please jumper the board for a free IRQ.
> > [ 1245.919389] scsi host2: Generic NCR5380/NCR53C400 SCSI, io_port 0x0, n_io_port 0, base 0xd8000, irq 0, can_queue 16, cmd_per_lun 2, sg_tablesize 128, this_id 7, flags { NCR53C400 }, USLEEP_POLL 3, USLEEP_WAITLONG 1250, options { AUTOPROBE_IRQ PSEUDO_DMA NCR53C400 }
> > [ 1246.376738] scsi 2:0:1:0: Direct-Access     QUANTUM  LP240S GM240S01X 4.6  PQ: 0 ANSI: 2 CCS
> > [ 1248.202198] sd 2:0:1:0: Attached scsi generic sg1 type 0
> > [ 1248.420856] 53C400r: no 53C80 gated irq after transfer
> > [ 1248.420948] 53C400r: no end dma signal
> > [ 1248.422459] sd 2:0:1:0: [sdb] Sector size 0 reported, assuming 512.
> > 
> > Seems that the PSEUDO_DMA is broken.
> 
> That's been my experience with mac_scsi also (going back 10 years). I'm 
> told that it used to work in v2.2. PIO was always usable though hopelessly 
> slow.
> 
> I haven't yet done any work on the PDMA problem with mac_scsi because 
> crashing bugs and the forked core driver seemed to be the more pressing 
> problems. And resolving the fork has implications for all of the DMA 
> variations anyway.

PDMA seems to be broken in multiple ways. NCR5380_pread cannot process less
than 128 bytes. In fact, 53C400 datasheet says that it's HW limitation:
non-modulo-128-byte transfers should use PIO.

Adding
        transfersize = round_down(transfersize, 128);
to generic_NCR5380_dma_xfer_len() improves the situation a bit.

After modprobe, some small reads (8, 4, 24 and 64 bytes) are done using PIO,
then eight 512-byte reads using PDMA and then it fails on a 254-byte read.
First 128 bytes are read using PDMA and the next PDMA operation hangs waiting
forever for the host buffer to be ready.

-- 
Ondrej Zary

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

* Re: [PATCH 00/71] More fixes, cleanup and modernization for NCR5380 drivers
  2015-11-23 22:55                 ` Ondrej Zary
@ 2015-11-24  1:21                   ` Finn Thain
  2015-11-24  8:04                     ` Ondrej Zary
  0 siblings, 1 reply; 268+ messages in thread
From: Finn Thain @ 2015-11-24  1:21 UTC (permalink / raw)
  To: Ondrej Zary
  Cc: Sam Creasey, Michael Schmitz, James E.J. Bottomley, linux-m68k,
	linux-scsi, linux-kernel


On Mon, 23 Nov 2015, Ondrej Zary wrote:

> 
> PDMA seems to be broken in multiple ways. NCR5380_pread cannot process 
> less than 128 bytes. In fact, 53C400 datasheet says that it's HW 
> limitation: non-modulo-128-byte transfers should use PIO.
> 
> Adding
>         transfersize = round_down(transfersize, 128);
> to generic_NCR5380_dma_xfer_len() improves the situation a bit.
> 
> After modprobe, some small reads (8, 4, 24 and 64 bytes) are done using 
> PIO, then eight 512-byte reads using PDMA and then it fails on a 
> 254-byte read. First 128 bytes are read using PDMA and the next PDMA 
> operation hangs waiting forever for the host buffer to be ready.
> 

A 128-byte PDMA receive followed by 126-byte PDMA receive? I don't see how
that is possible given round_down(126, 128) == 0. Was this the actual
'len' argument to NCR5380_pread() in g_NCR5380.c?

BTW, I presume that FLAG_NO_DMA_FIXUPS was set (which is the case if you
pass ncr_53c400=1 option with modprobe). Otherwise you could see PDMA IO
sizes like 127 etc.

-- 

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

* Re: [PATCH 00/71] More fixes, cleanup and modernization for NCR5380 drivers
  2015-11-24  1:21                   ` Finn Thain
@ 2015-11-24  8:04                     ` Ondrej Zary
  2015-11-24  9:13                       ` Finn Thain
  0 siblings, 1 reply; 268+ messages in thread
From: Ondrej Zary @ 2015-11-24  8:04 UTC (permalink / raw)
  To: Finn Thain
  Cc: Sam Creasey, Michael Schmitz, James E.J. Bottomley, linux-m68k,
	linux-scsi, linux-kernel

On Tuesday 24 November 2015, Finn Thain wrote:
> 
> On Mon, 23 Nov 2015, Ondrej Zary wrote:
> 
> > 
> > PDMA seems to be broken in multiple ways. NCR5380_pread cannot process 
> > less than 128 bytes. In fact, 53C400 datasheet says that it's HW 
> > limitation: non-modulo-128-byte transfers should use PIO.
> > 
> > Adding
> >         transfersize = round_down(transfersize, 128);
> > to generic_NCR5380_dma_xfer_len() improves the situation a bit.
> > 
> > After modprobe, some small reads (8, 4, 24 and 64 bytes) are done using 
> > PIO, then eight 512-byte reads using PDMA and then it fails on a 
> > 254-byte read. First 128 bytes are read using PDMA and the next PDMA 
> > operation hangs waiting forever for the host buffer to be ready.
> > 
> 
> A 128-byte PDMA receive followed by 126-byte PDMA receive? I don't see how
> that is possible given round_down(126, 128) == 0. Was this the actual
> 'len' argument to NCR5380_pread() in g_NCR5380.c?

No 126-byte PDMA. The 126 bytes were probably lost (or mixed with the next
read?). The next read was also 254 bytes so another 128-byte PDMA transfer.

Then modified NCR5380_information_transfer() to transfer the remaining data
(126 bytes in this case) using PIO. It did not help, the next PDMA transfer
failed too.

> BTW, I presume that FLAG_NO_DMA_FIXUPS was set (which is the case if you
> pass ncr_53c400=1 option with modprobe). Otherwise you could see PDMA IO
> sizes like 127 etc.

Yes, the flag was set.

-- 
Ondrej Zary

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

* Re: [PATCH 00/71] More fixes, cleanup and modernization for NCR5380 drivers
  2015-11-24  8:04                     ` Ondrej Zary
@ 2015-11-24  9:13                       ` Finn Thain
  2015-11-24 12:03                         ` Ondrej Zary
  2015-11-24 21:40                         ` Ondrej Zary
  0 siblings, 2 replies; 268+ messages in thread
From: Finn Thain @ 2015-11-24  9:13 UTC (permalink / raw)
  To: Ondrej Zary
  Cc: Sam Creasey, Michael Schmitz, James E.J. Bottomley, linux-m68k,
	linux-scsi, linux-kernel


On Tue, 24 Nov 2015, Ondrej Zary wrote:

> On Tuesday 24 November 2015, Finn Thain wrote:
> > 
> > On Mon, 23 Nov 2015, Ondrej Zary wrote:
> > 
> > > 
> > > PDMA seems to be broken in multiple ways. NCR5380_pread cannot 
> > > process less than 128 bytes. In fact, 53C400 datasheet says that 
> > > it's HW limitation: non-modulo-128-byte transfers should use PIO.
> > > 
> > > Adding
> > >         transfersize = round_down(transfersize, 128);
> > > to generic_NCR5380_dma_xfer_len() improves the situation a bit.
> > > 
> > > After modprobe, some small reads (8, 4, 24 and 64 bytes) are done 
> > > using PIO, then eight 512-byte reads using PDMA and then it fails on 
> > > a 254-byte read. First 128 bytes are read using PDMA and the next 
> > > PDMA operation hangs waiting forever for the host buffer to be 
> > > ready.
> > > 
> > 
> > A 128-byte PDMA receive followed by 126-byte PDMA receive? I don't see 
> > how that is possible given round_down(126, 128) == 0. Was this the 
> > actual 'len' argument to NCR5380_pread() in g_NCR5380.c?
> 
> No 126-byte PDMA. The 126 bytes were probably lost (or mixed with the 
> next read?).

When you said, the "PDMA operation hangs waiting forever", I figured that 
you had hit an infinite loop in NCR5380_pread()... but now I'm lost.

My main concern here is to confirm that I didn't break anything e.g. with 
patch 24 or 41. It would be nice to know that this hang is not the result 
of a new bug.

> The next read was also 254 bytes so another 128-byte PDMA transfer.
> 
> Then modified NCR5380_information_transfer() to transfer the remaining 
> data (126 bytes in this case) using PIO. It did not help, the next PDMA 
> transfer failed too.
> 

AFAICT, no change to NCR5380_information_transfer() should be needed. It 
was always meant to cope with the need to split a transfer between (P)DMA 
and PIO.

If the target is expecting the remaining 126 bytes, it will keep the bus 
in DATA OUT phase, and the next iteration of the loop
	while ((cmd = hostdata->connected)) { }
will call NCR5380_transfer_pio() for the remaining bytes. If the target 
never asserts REQ, that transfer will never happen, but then the command 
should timeout and get aborted, to handle the possibility that a "PDMA 
operation hangs waiting forever".

A protocol analyzer would be useful to debug this. I get a lot of value 
from a bus terminator block that has LEDs for the various control signals.
Failing that, you might need to place,
#define NDEBUG (NDEBUG_INFORMATION | NDEBUG_HANDSHAKE | NDEBUG_PIO | NDEBUG_DMA | NDEBUG_MAIN)
at the top of g_NCR5380.c.

-- 

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

* Re: [PATCH 00/71] More fixes, cleanup and modernization for NCR5380 drivers
  2015-11-24  9:13                       ` Finn Thain
@ 2015-11-24 12:03                         ` Ondrej Zary
  2015-11-24 18:04                           ` Ondrej Zary
  2015-11-24 21:40                         ` Ondrej Zary
  1 sibling, 1 reply; 268+ messages in thread
From: Ondrej Zary @ 2015-11-24 12:03 UTC (permalink / raw)
  To: Finn Thain
  Cc: Sam Creasey, Michael Schmitz, James E.J. Bottomley, linux-m68k,
	linux-scsi, linux-kernel

On Tuesday 24 November 2015, Finn Thain wrote:
> 
> On Tue, 24 Nov 2015, Ondrej Zary wrote:
> 
> > On Tuesday 24 November 2015, Finn Thain wrote:
> > > 
> > > On Mon, 23 Nov 2015, Ondrej Zary wrote:
> > > 
> > > > 
> > > > PDMA seems to be broken in multiple ways. NCR5380_pread cannot 
> > > > process less than 128 bytes. In fact, 53C400 datasheet says that 
> > > > it's HW limitation: non-modulo-128-byte transfers should use PIO.
> > > > 
> > > > Adding
> > > >         transfersize = round_down(transfersize, 128);
> > > > to generic_NCR5380_dma_xfer_len() improves the situation a bit.
> > > > 
> > > > After modprobe, some small reads (8, 4, 24 and 64 bytes) are done 
> > > > using PIO, then eight 512-byte reads using PDMA and then it fails on 
> > > > a 254-byte read. First 128 bytes are read using PDMA and the next 
> > > > PDMA operation hangs waiting forever for the host buffer to be 
> > > > ready.
> > > > 
> > > 
> > > A 128-byte PDMA receive followed by 126-byte PDMA receive? I don't see 
> > > how that is possible given round_down(126, 128) == 0. Was this the 
> > > actual 'len' argument to NCR5380_pread() in g_NCR5380.c?
> > 
> > No 126-byte PDMA. The 126 bytes were probably lost (or mixed with the 
> > next read?).
> 
> When you said, the "PDMA operation hangs waiting forever", I figured that 
> you had hit an infinite loop in NCR5380_pread()... but now I'm lost.

The first 128-byte PDMA ended successfully (ignoring what happened to the
remaining 126 bytes), then a next request for 254 bytes came. This resulted
in a new 128-byte PDMA and that hanged (in one of its possibly infinite loops
without a timeout).

> My main concern here is to confirm that I didn't break anything e.g. with 
> patch 24 or 41. It would be nice to know that this hang is not the result 
> of a new bug.

PDMA was already broken before so it's hard to tell. I can try to modify
the unpatched driver to see if PDMA is broken the same way.

> > The next read was also 254 bytes so another 128-byte PDMA transfer.
> > 
> > Then modified NCR5380_information_transfer() to transfer the remaining 
> > data (126 bytes in this case) using PIO. It did not help, the next PDMA 
> > transfer failed too.
> > 
> 
> AFAICT, no change to NCR5380_information_transfer() should be needed. It 
> was always meant to cope with the need to split a transfer between (P)DMA 
> and PIO.
> 
> If the target is expecting the remaining 126 bytes, it will keep the bus 
> in DATA OUT phase, and the next iteration of the loop
> 	while ((cmd = hostdata->connected)) { }
> will call NCR5380_transfer_pio() for the remaining bytes. If the target 
> never asserts REQ, that transfer will never happen, but then the command 
> should timeout and get aborted, to handle the possibility that a "PDMA 
> operation hangs waiting forever".

Thanks for explanation.

> A protocol analyzer would be useful to debug this. I get a lot of value 
> from a bus terminator block that has LEDs for the various control signals.
> Failing that, you might need to place,
> #define NDEBUG (NDEBUG_INFORMATION | NDEBUG_HANDSHAKE | NDEBUG_PIO | NDEBUG_DMA | NDEBUG_MAIN)
> at the top of g_NCR5380.c.


-- 
Ondrej Zary

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

* Re: [PATCH 00/71] More fixes, cleanup and modernization for NCR5380 drivers
  2015-11-24 12:03                         ` Ondrej Zary
@ 2015-11-24 18:04                           ` Ondrej Zary
  0 siblings, 0 replies; 268+ messages in thread
From: Ondrej Zary @ 2015-11-24 18:04 UTC (permalink / raw)
  To: Finn Thain
  Cc: Sam Creasey, Michael Schmitz, James E.J. Bottomley, linux-m68k,
	linux-scsi, linux-kernel

On Tuesday 24 November 2015 13:03:17 Ondrej Zary wrote:
> On Tuesday 24 November 2015, Finn Thain wrote:
> > 
> > On Tue, 24 Nov 2015, Ondrej Zary wrote:
> > 
> > > On Tuesday 24 November 2015, Finn Thain wrote:
> > > > 
> > > > On Mon, 23 Nov 2015, Ondrej Zary wrote:
> > > > 
> > > > > 
> > > > > PDMA seems to be broken in multiple ways. NCR5380_pread cannot 
> > > > > process less than 128 bytes. In fact, 53C400 datasheet says that 
> > > > > it's HW limitation: non-modulo-128-byte transfers should use PIO.
> > > > > 
> > > > > Adding
> > > > >         transfersize = round_down(transfersize, 128);
> > > > > to generic_NCR5380_dma_xfer_len() improves the situation a bit.
> > > > > 
> > > > > After modprobe, some small reads (8, 4, 24 and 64 bytes) are done 
> > > > > using PIO, then eight 512-byte reads using PDMA and then it fails on 
> > > > > a 254-byte read. First 128 bytes are read using PDMA and the next 
> > > > > PDMA operation hangs waiting forever for the host buffer to be 
> > > > > ready.
> > > > > 
> > > > 
> > > > A 128-byte PDMA receive followed by 126-byte PDMA receive? I don't see 
> > > > how that is possible given round_down(126, 128) == 0. Was this the 
> > > > actual 'len' argument to NCR5380_pread() in g_NCR5380.c?
> > > 
> > > No 126-byte PDMA. The 126 bytes were probably lost (or mixed with the 
> > > next read?).
> > 
> > When you said, the "PDMA operation hangs waiting forever", I figured that 
> > you had hit an infinite loop in NCR5380_pread()... but now I'm lost.
> 
> The first 128-byte PDMA ended successfully (ignoring what happened to the
> remaining 126 bytes), then a next request for 254 bytes came. This resulted
> in a new 128-byte PDMA and that hanged (in one of its possibly infinite loops
> without a timeout).
> 
> > My main concern here is to confirm that I didn't break anything e.g. with 
> > patch 24 or 41. It would be nice to know that this hang is not the result 
> > of a new bug.
> 
> PDMA was already broken before so it's hard to tell. I can try to modify
> the unpatched driver to see if PDMA is broken the same way.

Just tested the driver without your patches and it's broken exactly the same
way.

-- 
Ondrej Zary

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

* Re: [PATCH 22/71] ncr5380: Eliminate selecting state
  2015-11-18  8:35   ` Finn Thain
  (?)
@ 2015-11-24 19:08   ` Ondrej Zary
  2015-11-25  3:17     ` Finn Thain
  -1 siblings, 1 reply; 268+ messages in thread
From: Ondrej Zary @ 2015-11-24 19:08 UTC (permalink / raw)
  To: Finn Thain
  Cc: James E.J. Bottomley, Michael Schmitz, linux-m68k, linux-scsi,
	linux-kernel

On Wednesday 18 November 2015 09:35:17 Finn Thain wrote:
> Linux v2.1.105 changed the algorithm for polling for the BSY signal
> in NCR5380_select() and NCR5380_main().
> 
> Presently, this code has a bug. Back then, NCR5380_set_timer(hostdata, 1)
> meant reschedule main() after sleeping for 10 ms. Repeated 25 times this
> provided the recommended 250 ms selection time-out delay. This got broken
> when HZ became configurable.
> 
> We could fix this but there's no need to reschedule the main loop. This
> BSY polling presently happens when the NCR5380_main() work queue item
> calls NCR5380_select(), which in turn schedules NCR5380_main(), which
> calls NCR5380_select() again, and so on.
> 
> This algorithm is a deviation from the simpler one in atari_NCR5380.c.
> The extra complexity and state is pointless. There's no reason to
> stop selection half-way and return to to the main loop when the main
> loop can do nothing useful until selection completes.
> 
> So just poll for BSY. We can sleep while polling now that we have a
> suitable workqueue.

Bisecting slow module initialization pointed to this commit.

Before this commit (2 seconds):
[   60.317374] scsi host2: Generic NCR5380/NCR53C400 SCSI, io_port 0x0, n_io_port 0, base 0xd8000, irq 0, can_queue 16, cmd_per_lun 2, sg_tablesize 128, this_id 7, flags { NCR53C400 }, USLEEP_POLL 3, USLEEP_SLEEP 50, options { AUTOPROBE_IRQ PSEUDO_DMA }
[   60.780715] scsi 2:0:1:0: Direct-Access     QUANTUM  LP240S GM240S01X 4.6  PQ: 0 ANSI: 2 CCS
[   62.606260] sd 2:0:1:0: Attached scsi generic sg1 type 0


After this commit (22 seconds):
[  137.511711] scsi host2: Generic NCR5380/NCR53C400 SCSI, io_port 0x0, n_io_port 0, base 0xd8000, irq 0, can_queue 16, cmd_per_lun 2, sg_tablesize 128, this_id 7, flags { NCR53C400 }, USLEEP_POLL 3, USLEEP_SLEEP 50, options { AUTOPROBE_IRQ PSEUDO_DMA }
[  145.028532] clocksource: timekeeping watchdog: Marking clocksource 'tsc' as unstable because the skew is too large:
[  145.029767] clocksource:                       'acpi_pm' wd_now: a49738 wd_last: f4da04 mask: ffffff
[  145.029828] clocksource:                       'tsc' cs_now: 2ea624698e cs_last: 2c710aa17f mask: ffffffffffffffff
[  145.032733] clocksource: Switched to clocksource acpi_pm
[  145.236951] scsi 2:0:1:0: Direct-Access     QUANTUM  LP240S GM240S01X 4.6  PQ: 0 ANSI: 2 CCS
[  159.959308] sd 2:0:1:0: Attached scsi generic sg1 type 0


-- 
Ondrej Zary

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

* Re: [PATCH 00/71] More fixes, cleanup and modernization for NCR5380 drivers
  2015-11-24  9:13                       ` Finn Thain
  2015-11-24 12:03                         ` Ondrej Zary
@ 2015-11-24 21:40                         ` Ondrej Zary
  2015-11-25  2:10                           ` Finn Thain
  1 sibling, 1 reply; 268+ messages in thread
From: Ondrej Zary @ 2015-11-24 21:40 UTC (permalink / raw)
  To: Finn Thain
  Cc: Sam Creasey, Michael Schmitz, James E.J. Bottomley, linux-m68k,
	linux-scsi, linux-kernel

On Tuesday 24 November 2015 10:13:17 Finn Thain wrote:
> 
> On Tue, 24 Nov 2015, Ondrej Zary wrote:
> 
> > On Tuesday 24 November 2015, Finn Thain wrote:
> > > 
> > > On Mon, 23 Nov 2015, Ondrej Zary wrote:
> > > 
> > > > 
> > > > PDMA seems to be broken in multiple ways. NCR5380_pread cannot 
> > > > process less than 128 bytes. In fact, 53C400 datasheet says that 
> > > > it's HW limitation: non-modulo-128-byte transfers should use PIO.
> > > > 
> > > > Adding
> > > >         transfersize = round_down(transfersize, 128);
> > > > to generic_NCR5380_dma_xfer_len() improves the situation a bit.
> > > > 
> > > > After modprobe, some small reads (8, 4, 24 and 64 bytes) are done 
> > > > using PIO, then eight 512-byte reads using PDMA and then it fails on 
> > > > a 254-byte read. First 128 bytes are read using PDMA and the next 
> > > > PDMA operation hangs waiting forever for the host buffer to be 
> > > > ready.
> > > > 
> > > 
> > > A 128-byte PDMA receive followed by 126-byte PDMA receive? I don't see 
> > > how that is possible given round_down(126, 128) == 0. Was this the 
> > > actual 'len' argument to NCR5380_pread() in g_NCR5380.c?
> > 
> > No 126-byte PDMA. The 126 bytes were probably lost (or mixed with the 
> > next read?).
> 
> When you said, the "PDMA operation hangs waiting forever", I figured that 
> you had hit an infinite loop in NCR5380_pread()... but now I'm lost.
> 
> My main concern here is to confirm that I didn't break anything e.g. with 
> patch 24 or 41. It would be nice to know that this hang is not the result 
> of a new bug.
> 
> > The next read was also 254 bytes so another 128-byte PDMA transfer.
> > 
> > Then modified NCR5380_information_transfer() to transfer the remaining 
> > data (126 bytes in this case) using PIO. It did not help, the next PDMA 
> > transfer failed too.
> > 
> 
> AFAICT, no change to NCR5380_information_transfer() should be needed. It 
> was always meant to cope with the need to split a transfer between (P)DMA 
> and PIO.

Instead of fixing split transfers, simply forced everything non-modulo-128 to
PIO:
--- a/drivers/scsi/g_NCR5380.c
+++ b/drivers/scsi/g_NCR5380.c
@@ -703,6 +703,10 @@ static int generic_NCR5380_dma_xfer_len(struct scsi_cmnd *cmd)
 	    !(cmd->SCp.this_residual % transfersize))
 		transfersize = 32 * 1024;

+	/* 53C400 datasheet: non-modulo-128-byte transfers should use PIO */
+	if (transfersize % 128)
+		transfersize = 0;
+
 	return transfersize;
 }

It seems to work and greatly improves performance:
# hdparm -t --direct /dev/sdb

/dev/sdb:
 Timing O_DIRECT disk reads:   4 MB in  4.84 seconds = 846.15 kB/sec

-- 
Ondrej Zary

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

* Re: [PATCH 00/71] More fixes, cleanup and modernization for NCR5380 drivers
  2015-11-24 21:40                         ` Ondrej Zary
@ 2015-11-25  2:10                           ` Finn Thain
  2015-11-25  9:04                             ` Ondrej Zary
  0 siblings, 1 reply; 268+ messages in thread
From: Finn Thain @ 2015-11-25  2:10 UTC (permalink / raw)
  To: Ondrej Zary
  Cc: Sam Creasey, Michael Schmitz, James E.J. Bottomley, linux-m68k,
	linux-scsi, linux-kernel


On Tue, 24 Nov 2015, Ondrej Zary wrote:

> On Tuesday 24 November 2015 10:13:17 Finn Thain wrote:
> > 
> > On Tue, 24 Nov 2015, Ondrej Zary wrote:
> > 
> > > On Tuesday 24 November 2015, Finn Thain wrote:
> > > > 
> > > > On Mon, 23 Nov 2015, Ondrej Zary wrote:
> > > > 
> > > > > 
> > > > > PDMA seems to be broken in multiple ways. NCR5380_pread cannot 
> > > > > process less than 128 bytes. In fact, 53C400 datasheet says that 
> > > > > it's HW limitation: non-modulo-128-byte transfers should use 
> > > > > PIO.
> > > > > 
> > > > > Adding
> > > > >         transfersize = round_down(transfersize, 128);
> > > > > to generic_NCR5380_dma_xfer_len() improves the situation a bit.
> > > > > 
> > > > > After modprobe, some small reads (8, 4, 24 and 64 bytes) are 
> > > > > done using PIO, then eight 512-byte reads using PDMA and then it 
> > > > > fails on a 254-byte read. First 128 bytes are read using PDMA 
> > > > > and the next PDMA operation hangs waiting forever for the host 
> > > > > buffer to be ready.
> > > > > 
> > > > 
> > > > A 128-byte PDMA receive followed by 126-byte PDMA receive? I don't 
> > > > see how that is possible given round_down(126, 128) == 0. Was this 
> > > > the actual 'len' argument to NCR5380_pread() in g_NCR5380.c?
> > > 
> > > No 126-byte PDMA. The 126 bytes were probably lost (or mixed with 
> > > the next read?).
> > [...]
> > > The next read was also 254 bytes so another 128-byte PDMA transfer.
> > > 
> > > Then modified NCR5380_information_transfer() to transfer the 
> > > remaining data (126 bytes in this case) using PIO. It did not help, 
> > > the next PDMA transfer failed too.
> > > 
> > 
> > AFAICT, no change to NCR5380_information_transfer() should be needed. 
> > It was always meant to cope with the need to split a transfer between 
> > (P)DMA and PIO.
> 
> Instead of fixing split transfers, simply forced everything 
> non-modulo-128 to PIO:

The need to split a transfer arises from early chip errata relating to DMA 
and the workarounds for them (see the comments in the source). That's why 
I believe that the driver was meant to be cope with this. But I don't have 
any experimental evidence for it.

I'm almost certain that these errata aren't applicable to your hardware. 
So I don't have any reason to think that your card will allow part of a 
transfer to be performed with PDMA and the rest with PIO. So I don't 
really object to the patch.

But I don't understand the need for it either: I have no idea what state 
the driver, chip and scsi bus were in when the 126-byte PIO transfer 
failed. If the PIO transfer didn't succeed then the entire command should 
have failed.

> --- a/drivers/scsi/g_NCR5380.c
> +++ b/drivers/scsi/g_NCR5380.c
> @@ -703,6 +703,10 @@ static int generic_NCR5380_dma_xfer_len(struct scsi_cmnd *cmd)
>  	    !(cmd->SCp.this_residual % transfersize))
>  		transfersize = 32 * 1024;
> 
> +	/* 53C400 datasheet: non-modulo-128-byte transfers should use PIO */

Do you have a download link for this datasheet?

> +	if (transfersize % 128)
> +		transfersize = 0;
> +
>  	return transfersize;
>  }
> 
> It seems to work and greatly improves performance:
> # hdparm -t --direct /dev/sdb
> 
> /dev/sdb:
>  Timing O_DIRECT disk reads:   4 MB in  4.84 seconds = 846.15 kB/sec
> 

Sounds about right...

-- 

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

* Re: [PATCH 22/71] ncr5380: Eliminate selecting state
  2015-11-24 19:08   ` Ondrej Zary
@ 2015-11-25  3:17     ` Finn Thain
  2015-11-25 21:59       ` Ondrej Zary
  0 siblings, 1 reply; 268+ messages in thread
From: Finn Thain @ 2015-11-25  3:17 UTC (permalink / raw)
  To: Ondrej Zary
  Cc: James E.J. Bottomley, Michael Schmitz, linux-m68k, linux-scsi,
	linux-kernel


On Tue, 24 Nov 2015, Ondrej Zary wrote:

> On Wednesday 18 November 2015 09:35:17 Finn Thain wrote:
> > Linux v2.1.105 changed the algorithm for polling for the BSY signal
> > in NCR5380_select() and NCR5380_main().
> > 
> > Presently, this code has a bug. Back then, NCR5380_set_timer(hostdata, 1)
> > meant reschedule main() after sleeping for 10 ms. Repeated 25 times this
> > provided the recommended 250 ms selection time-out delay. This got broken
> > when HZ became configurable.
> > 
> > We could fix this but there's no need to reschedule the main loop. This
> > BSY polling presently happens when the NCR5380_main() work queue item
> > calls NCR5380_select(), which in turn schedules NCR5380_main(), which
> > calls NCR5380_select() again, and so on.
> > 
> > This algorithm is a deviation from the simpler one in atari_NCR5380.c.
> > The extra complexity and state is pointless. There's no reason to
> > stop selection half-way and return to to the main loop when the main
> > loop can do nothing useful until selection completes.
> > 
> > So just poll for BSY. We can sleep while polling now that we have a
> > suitable workqueue.
> 
> Bisecting slow module initialization pointed to this commit.

That's disappointing. This patch removed some nasty code. Anyway, thanks 
for taking the trouble to bisect.

> 
> Before this commit (2 seconds):
> [   60.317374] scsi host2: Generic NCR5380/NCR53C400 SCSI, io_port 0x0, n_io_port 0, base 0xd8000, irq 0, can_queue 16, cmd_per_lun 2, sg_tablesize 128, this_id 7, flags { NCR53C400 }, USLEEP_POLL 3, USLEEP_SLEEP 50, options { AUTOPROBE_IRQ PSEUDO_DMA }
> [   60.780715] scsi 2:0:1:0: Direct-Access     QUANTUM  LP240S GM240S01X 4.6  PQ: 0 ANSI: 2 CCS
> [   62.606260] sd 2:0:1:0: Attached scsi generic sg1 type 0
> 
> 
> After this commit (22 seconds):
> [  137.511711] scsi host2: Generic NCR5380/NCR53C400 SCSI, io_port 0x0, n_io_port 0, base 0xd8000, irq 0, can_queue 16, cmd_per_lun 2, sg_tablesize 128, this_id 7, flags { NCR53C400 }, USLEEP_POLL 3, USLEEP_SLEEP 50, options { AUTOPROBE_IRQ PSEUDO_DMA }
> [  145.028532] clocksource: timekeeping watchdog: Marking clocksource 'tsc' as unstable because the skew is too large:
> [  145.029767] clocksource:                       'acpi_pm' wd_now: a49738 wd_last: f4da04 mask: ffffff
> [  145.029828] clocksource:                       'tsc' cs_now: 2ea624698e cs_last: 2c710aa17f mask: ffffffffffffffff
> [  145.032733] clocksource: Switched to clocksource acpi_pm

I figured that it was okay to sleep from an unbound CPU-intensive 
workqueue but doing so seems to cause problems. (See also patch 66/71 
"Fix soft lockups".)

Perhaps a kthread is needed instead of a workqueue? (This workqueue 
already has it's own kthread, but top shows that it doesn't accrue CPU 
time.)

> [  145.236951] scsi 2:0:1:0: Direct-Access     QUANTUM  LP240S GM240S01X 4.6  PQ: 0 ANSI: 2 CCS
> [  159.959308] sd 2:0:1:0: Attached scsi generic sg1 type 0
> 
> 

This problem doesn't show up on my hardware, and I'd like to know where 
those 22 seconds are being spent. Would you please apply the entire series 
and add,
#define NDEBUG (NDEBUG_ARBITRATION | NDEBUG_SELECTION | NDEBUG_MAIN)
to the top of g_NCR5380.c and send me the messages logged during modprobe?

-- 

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

* Re: [PATCH 00/71] More fixes, cleanup and modernization for NCR5380 drivers
  2015-11-25  2:10                           ` Finn Thain
@ 2015-11-25  9:04                             ` Ondrej Zary
  2015-11-25 11:50                               ` Finn Thain
  2015-11-25 23:01                               ` Ondrej Zary
  0 siblings, 2 replies; 268+ messages in thread
From: Ondrej Zary @ 2015-11-25  9:04 UTC (permalink / raw)
  To: Finn Thain
  Cc: Sam Creasey, Michael Schmitz, James E.J. Bottomley, linux-m68k,
	linux-scsi, linux-kernel

On Wednesday 25 November 2015, Finn Thain wrote:
> 
> On Tue, 24 Nov 2015, Ondrej Zary wrote:
> 
> > On Tuesday 24 November 2015 10:13:17 Finn Thain wrote:
> > > 
> > > On Tue, 24 Nov 2015, Ondrej Zary wrote:
> > > 
> > > > On Tuesday 24 November 2015, Finn Thain wrote:
> > > > > 
> > > > > On Mon, 23 Nov 2015, Ondrej Zary wrote:
> > > > > 
> > > > > > 
> > > > > > PDMA seems to be broken in multiple ways. NCR5380_pread cannot 
> > > > > > process less than 128 bytes. In fact, 53C400 datasheet says that 
> > > > > > it's HW limitation: non-modulo-128-byte transfers should use 
> > > > > > PIO.
> > > > > > 
> > > > > > Adding
> > > > > >         transfersize = round_down(transfersize, 128);
> > > > > > to generic_NCR5380_dma_xfer_len() improves the situation a bit.
> > > > > > 
> > > > > > After modprobe, some small reads (8, 4, 24 and 64 bytes) are 
> > > > > > done using PIO, then eight 512-byte reads using PDMA and then it 
> > > > > > fails on a 254-byte read. First 128 bytes are read using PDMA 
> > > > > > and the next PDMA operation hangs waiting forever for the host 
> > > > > > buffer to be ready.
> > > > > > 
> > > > > 
> > > > > A 128-byte PDMA receive followed by 126-byte PDMA receive? I don't 
> > > > > see how that is possible given round_down(126, 128) == 0. Was this 
> > > > > the actual 'len' argument to NCR5380_pread() in g_NCR5380.c?
> > > > 
> > > > No 126-byte PDMA. The 126 bytes were probably lost (or mixed with 
> > > > the next read?).
> > > [...]
> > > > The next read was also 254 bytes so another 128-byte PDMA transfer.
> > > > 
> > > > Then modified NCR5380_information_transfer() to transfer the 
> > > > remaining data (126 bytes in this case) using PIO. It did not help, 
> > > > the next PDMA transfer failed too.
> > > > 
> > > 
> > > AFAICT, no change to NCR5380_information_transfer() should be needed. 
> > > It was always meant to cope with the need to split a transfer between 
> > > (P)DMA and PIO.
> > 
> > Instead of fixing split transfers, simply forced everything 
> > non-modulo-128 to PIO:
> 
> The need to split a transfer arises from early chip errata relating to DMA 
> and the workarounds for them (see the comments in the source). That's why 
> I believe that the driver was meant to be cope with this. But I don't have 
> any experimental evidence for it.
> 
> I'm almost certain that these errata aren't applicable to your hardware. 
> So I don't have any reason to think that your card will allow part of a 
> transfer to be performed with PDMA and the rest with PIO. So I don't 
> really object to the patch.
> 
> But I don't understand the need for it either: I have no idea what state 
> the driver, chip and scsi bus were in when the 126-byte PIO transfer 
> failed. If the PIO transfer didn't succeed then the entire command should 
> have failed.

The patch was just a quick hack to confirm that PDMA is not completely broken.
Now we know that it mostly works so I can investigate the partial PIO problem.

> > --- a/drivers/scsi/g_NCR5380.c
> > +++ b/drivers/scsi/g_NCR5380.c
> > @@ -703,6 +703,10 @@ static int generic_NCR5380_dma_xfer_len(struct scsi_cmnd *cmd)
> >  	    !(cmd->SCp.this_residual % transfersize))
> >  		transfersize = 32 * 1024;
> > 
> > +	/* 53C400 datasheet: non-modulo-128-byte transfers should use PIO */
> 
> Do you have a download link for this datasheet?

http://bitsavers.trailing-edge.com/pdf/ncr/scsi/NCR_53C400.pdf

53C400A datasheet would be great too but haven't found any.
I think that PDMA should work with 53C400A too but seems that the driver was
never able to do it.

Although there is code for port-mapped transfer in NCR5380_pread(),
NCR53C400_register_offset is defined to 0 in the port-mapped case. The C400_
register offsets are thus defined with negative offset:

#define C400_CONTROL_STATUS_REG NCR53C400_register_offset-8
#define C400_BLOCK_COUNTER_REG   NCR53C400_register_offset-7
#define C400_RESUME_TRANSFER_REG NCR53C400_register_offset-6
#define C400_HOST_BUFFER         NCR53C400_register_offset-4

This is probably OK for a port-mapped 53C400 (such card must have some glue
decoding logic as the 53C400 chip itself can do memory-mapping only) because:

                /*
                 * On NCR53C400 boards, NCR5380 registers are mapped 8 past
                 * the base address.
                 */
                if (overrides[current_override].board == BOARD_NCR53C400)
                        instance->io_port += 8;

This means that on a 53C400, first 5380 register will be at base+8 and first
C400_ register at base.

But on a 53C400A, the 5380 registers are mapped on the base address so the
C400_ registers would be below the base, which is obviously wrong. I hope that
PDMA will work if I fix the C400_ registers mapping.

> > +	if (transfersize % 128)
> > +		transfersize = 0;
> > +
> >  	return transfersize;
> >  }
> > 
> > It seems to work and greatly improves performance:
> > # hdparm -t --direct /dev/sdb
> > 
> > /dev/sdb:
> >  Timing O_DIRECT disk reads:   4 MB in  4.84 seconds = 846.15 kB/sec
> > 
> 
> Sounds about right...
> 

-- 
Ondrej Zary

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

* Re: [PATCH 00/71] More fixes, cleanup and modernization for NCR5380 drivers
  2015-11-25  9:04                             ` Ondrej Zary
@ 2015-11-25 11:50                               ` Finn Thain
  2015-11-25 23:01                               ` Ondrej Zary
  1 sibling, 0 replies; 268+ messages in thread
From: Finn Thain @ 2015-11-25 11:50 UTC (permalink / raw)
  To: Ondrej Zary
  Cc: Sam Creasey, Michael Schmitz, James E.J. Bottomley, linux-m68k,
	linux-scsi, linux-kernel


On Wed, 25 Nov 2015, Ondrej Zary wrote:

> On Wednesday 25 November 2015, Finn Thain wrote:
> > 
> > On Tue, 24 Nov 2015, Ondrej Zary wrote:
> > 
> > > Instead of fixing split transfers, simply forced everything 
> > > non-modulo-128 to PIO:
> > 
> > [...]
> > I don't have any reason to think that your card will allow part of 
> > a transfer to be performed with PDMA and the rest with PIO. So I don't 
> > really object to the patch.
> > 

>From looking at the datasheet, I think your patch is correct.

Your patch needs to be applied after mine, so if you will sign-off, I'll 
include it in the series with your Signed-off-by and "From:" header.

> > But I don't understand the need for it either: I have no idea what 
> > state the driver, chip and scsi bus were in when the 126-byte PIO 
> > transfer failed. If the PIO transfer didn't succeed then the entire 
> > command should have failed.
> 
> The patch was just a quick hack to confirm that PDMA is not completely 
> broken.
> Now we know that it mostly works so I can investigate the partial PIO 
> problem.
> 

There may not be any problem to investigate. Because this 53C80 core is 
embedded in other logic, it's hard to say whether or not the partial PIO 
algorithm could be expected to work at all.

Besides, the DMA errata don't apply to this core. And large transfers will 
always be divisible by 128 bytes so there's very little to be gained.

> [...]
> 
> 53C400A datasheet would be great too but haven't found any.

I don't have one either.

-- 

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

* [PATCH 72/71] ncr5380: Fix pseudo-DMA
  2015-11-18  8:34 ` Finn Thain
                   ` (72 preceding siblings ...)
  (?)
@ 2015-11-25 21:34 ` Ondrej Zary
  -1 siblings, 0 replies; 268+ messages in thread
From: Ondrej Zary @ 2015-11-25 21:34 UTC (permalink / raw)
  To: Finn Thain, Michael Schmitz, linux-m68k, linux-scsi, linux-kernel

Pseudo-DMA (PDMA) has been broken for ages, resulting in hangs on
53C400-based cards.

According to 53C400 datasheet, PDMA transfer length must be a multiple
of 128. Check if that's true and use PIO if it's not.

This makes PDMA work on 53C400 (Canon FG2-5202).

Signed-off-by: Ondrej Zary <linux@rainbow-software.org>
---
 drivers/scsi/g_NCR5380.c |    4 ++++
 1 file changed, 4 insertions(+)

diff --git a/drivers/scsi/g_NCR5380.c b/drivers/scsi/g_NCR5380.c
index 0daffe2..a9a237f 100644
--- a/drivers/scsi/g_NCR5380.c
+++ b/drivers/scsi/g_NCR5380.c
@@ -703,6 +703,10 @@ static int generic_NCR5380_dma_xfer_len(struct scsi_cmnd *cmd)
 	    !(cmd->SCp.this_residual % transfersize))
 		transfersize = 32 * 1024;
 
+	/* 53C400 datasheet: non-modulo-128-byte transfers should use PIO */
+	if (transfersize % 128)
+		transfersize = 0;
+
 	return transfersize;
 }
 
-- 
Ondrej Zary


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

* Re: [PATCH 22/71] ncr5380: Eliminate selecting state
  2015-11-25  3:17     ` Finn Thain
@ 2015-11-25 21:59       ` Ondrej Zary
  2015-11-26 10:23         ` Finn Thain
  0 siblings, 1 reply; 268+ messages in thread
From: Ondrej Zary @ 2015-11-25 21:59 UTC (permalink / raw)
  To: Finn Thain
  Cc: James E.J. Bottomley, Michael Schmitz, linux-m68k, linux-scsi,
	linux-kernel

On Wednesday 25 November 2015 04:17:09 Finn Thain wrote:
> 
> On Tue, 24 Nov 2015, Ondrej Zary wrote:
> 
> > On Wednesday 18 November 2015 09:35:17 Finn Thain wrote:
> > > Linux v2.1.105 changed the algorithm for polling for the BSY signal
> > > in NCR5380_select() and NCR5380_main().
> > > 
> > > Presently, this code has a bug. Back then, NCR5380_set_timer(hostdata, 1)
> > > meant reschedule main() after sleeping for 10 ms. Repeated 25 times this
> > > provided the recommended 250 ms selection time-out delay. This got broken
> > > when HZ became configurable.
> > > 
> > > We could fix this but there's no need to reschedule the main loop. This
> > > BSY polling presently happens when the NCR5380_main() work queue item
> > > calls NCR5380_select(), which in turn schedules NCR5380_main(), which
> > > calls NCR5380_select() again, and so on.
> > > 
> > > This algorithm is a deviation from the simpler one in atari_NCR5380.c.
> > > The extra complexity and state is pointless. There's no reason to
> > > stop selection half-way and return to to the main loop when the main
> > > loop can do nothing useful until selection completes.
> > > 
> > > So just poll for BSY. We can sleep while polling now that we have a
> > > suitable workqueue.
> > 
> > Bisecting slow module initialization pointed to this commit.
> 
> That's disappointing. This patch removed some nasty code. Anyway, thanks 
> for taking the trouble to bisect.
> 
> > 
> > Before this commit (2 seconds):
> > [   60.317374] scsi host2: Generic NCR5380/NCR53C400 SCSI, io_port 0x0, n_io_port 0, base 0xd8000, irq 0, can_queue 16, cmd_per_lun 2, sg_tablesize 128, this_id 7, flags { NCR53C400 }, USLEEP_POLL 3, USLEEP_SLEEP 50, options { AUTOPROBE_IRQ PSEUDO_DMA }
> > [   60.780715] scsi 2:0:1:0: Direct-Access     QUANTUM  LP240S GM240S01X 4.6  PQ: 0 ANSI: 2 CCS
> > [   62.606260] sd 2:0:1:0: Attached scsi generic sg1 type 0
> > 
> > 
> > After this commit (22 seconds):
> > [  137.511711] scsi host2: Generic NCR5380/NCR53C400 SCSI, io_port 0x0, n_io_port 0, base 0xd8000, irq 0, can_queue 16, cmd_per_lun 2, sg_tablesize 128, this_id 7, flags { NCR53C400 }, USLEEP_POLL 3, USLEEP_SLEEP 50, options { AUTOPROBE_IRQ PSEUDO_DMA }
> > [  145.028532] clocksource: timekeeping watchdog: Marking clocksource 'tsc' as unstable because the skew is too large:
> > [  145.029767] clocksource:                       'acpi_pm' wd_now: a49738 wd_last: f4da04 mask: ffffff
> > [  145.029828] clocksource:                       'tsc' cs_now: 2ea624698e cs_last: 2c710aa17f mask: ffffffffffffffff
> > [  145.032733] clocksource: Switched to clocksource acpi_pm
> 
> I figured that it was okay to sleep from an unbound CPU-intensive 
> workqueue but doing so seems to cause problems. (See also patch 66/71 
> "Fix soft lockups".)
> 
> Perhaps a kthread is needed instead of a workqueue? (This workqueue 
> already has it's own kthread, but top shows that it doesn't accrue CPU 
> time.)
> 
> > [  145.236951] scsi 2:0:1:0: Direct-Access     QUANTUM  LP240S GM240S01X 4.6  PQ: 0 ANSI: 2 CCS
> > [  159.959308] sd 2:0:1:0: Attached scsi generic sg1 type 0
> > 
> > 
> 
> This problem doesn't show up on my hardware, and I'd like to know where 
> those 22 seconds are being spent. Would you please apply the entire series 
> and add,
> #define NDEBUG (NDEBUG_ARBITRATION | NDEBUG_SELECTION | NDEBUG_MAIN)
> to the top of g_NCR5380.c and send me the messages logged during modprobe?

 [  397.014581] scsi host2: Generic NCR5380/NCR53C400 SCSI, io_port 0x0, n_io_port 0, base 0xd8000, irq 0, can_queue 16, cmd_per_lun 2, sg_tablesize 128, this_id 7, flags { NO_DMA_FIXUP }, options { AUTOPROBE_IRQ PSEUDO_DMA }
[  412.099695] STATUS_REG: 00
BASR: 08
ICR: 00
MODE: 00
[  412.103625] STATUS_REG: 00
BASR: 08
ICR: 00
MODE: 00
[  412.110503] scsi 2:0:1:0: Direct-Access     QUANTUM  LP240S GM240S01X 4.6  PQ: 0 ANSI: 2 CCS
[  412.110892] STATUS_REG: 00
BASR: 08
ICR: 00
MODE: 00
[  412.114154] STATUS_REG: 00
BASR: 08
ICR: 00
MODE: 00
[  412.119733] STATUS_REG: 00
BASR: 08
ICR: 00
MODE: 00
[  427.198108] STATUS_REG: 00
BASR: 08
ICR: 00
MODE: 00
[  442.276586] STATUS_REG: 00
BASR: 08
ICR: 00
MODE: 00
[  457.354592] STATUS_REG: 00
BASR: 08
ICR: 00
MODE: 00
[  472.432999] STATUS_REG: 00
BASR: 08
ICR: 00
MODE: 00
[  487.513027] sd 2:0:1:0: Attached scsi generic sg1 type 0



-- 
Ondrej Zary

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

* Re: [PATCH 00/71] More fixes, cleanup and modernization for NCR5380 drivers
  2015-11-25  9:04                             ` Ondrej Zary
  2015-11-25 11:50                               ` Finn Thain
@ 2015-11-25 23:01                               ` Ondrej Zary
  1 sibling, 0 replies; 268+ messages in thread
From: Ondrej Zary @ 2015-11-25 23:01 UTC (permalink / raw)
  To: Finn Thain
  Cc: Sam Creasey, Michael Schmitz, James E.J. Bottomley, linux-m68k,
	linux-scsi, linux-kernel

On Wednesday 25 November 2015 10:04:10 Ondrej Zary wrote:
> I think that PDMA should work with 53C400A too but seems that the driver was
> never able to do it.
> 
> Although there is code for port-mapped transfer in NCR5380_pread(),
> NCR53C400_register_offset is defined to 0 in the port-mapped case. The C400_
> register offsets are thus defined with negative offset:
> 
> #define C400_CONTROL_STATUS_REG NCR53C400_register_offset-8
> #define C400_BLOCK_COUNTER_REG   NCR53C400_register_offset-7
> #define C400_RESUME_TRANSFER_REG NCR53C400_register_offset-6
> #define C400_HOST_BUFFER         NCR53C400_register_offset-4
> 
> This is probably OK for a port-mapped 53C400 (such card must have some glue
> decoding logic as the 53C400 chip itself can do memory-mapping only) because:
> 
>                 /*
>                  * On NCR53C400 boards, NCR5380 registers are mapped 8 past
>                  * the base address.
>                  */
>                 if (overrides[current_override].board == BOARD_NCR53C400)
>                         instance->io_port += 8;
> 
> This means that on a 53C400, first 5380 register will be at base+8 and first
> C400_ register at base.
> 
> But on a 53C400A, the 5380 registers are mapped on the base address so the
> C400_ registers would be below the base, which is obviously wrong. I hope that
> PDMA will work if I fix the C400_ registers mapping.

A quick hack (breaks other chips, needs more work for proper mapping on all
chips):

--- a/drivers/scsi/NCR5380.h
+++ b/drivers/scsi/NCR5380.h
@@ -163,7 +163,7 @@
 /* Write any value to this register to start an ini mode DMA receive */
 #define START_DMA_INITIATOR_RECEIVE_REG 7      /* wo */

-#define C400_CONTROL_STATUS_REG NCR53C400_register_offset-8    /* rw */
+#define C400_CONTROL_STATUS_REG 9      /* rw */

 #define CSR_RESET              0x80    /* wo  Resets 53c400 */
 #define CSR_53C80_REG          0x80    /* ro  5380 registers busy */
@@ -182,13 +182,13 @@
 #endif

 /* Number of 128-byte blocks to be transferred */
-#define C400_BLOCK_COUNTER_REG   NCR53C400_register_offset-7   /* rw */
+#define C400_BLOCK_COUNTER_REG   10    /* rw */

 /* Resume transfer after disconnect */
-#define C400_RESUME_TRANSFER_REG NCR53C400_register_offset-6   /* wo */
+#define C400_RESUME_TRANSFER_REG 11    /* wo */

 /* Access to host buffer stack */
-#define C400_HOST_BUFFER         NCR53C400_register_offset-4   /* rw */
+#define C400_HOST_BUFFER         8     /* rw */


 /* Note : PHASE_* macros are based on the values of the STATUS register */
--- a/drivers/scsi/g_NCR5380.c
+++ b/drivers/scsi/g_NCR5380.c
@@ -323,7 +323,10 @@ static int __init generic_NCR5380_detect(struct scsi_host_template *tpnt)
 #endif
                        break;
                case BOARD_NCR53C400A:
+                       flags = FLAG_NO_DMA_FIXUP;
+#ifndef PSEUDO_DMA
                        flags = FLAG_NO_PSEUDO_DMA;
+#endif
                        ports = ncr_53c400a_ports;
                        break;
                case BOARD_DTC3181E:
@@ -414,7 +417,8 @@ static int __init generic_NCR5380_detect(struct scsi_host_template *tpnt)
                if (NCR5380_init(instance, flags))
                        goto out_unregister;

-               if (overrides[current_override].board == BOARD_NCR53C400)
+               if (overrides[current_override].board == BOARD_NCR53C400 ||
+                   overrides[current_override].board == BOARD_NCR53C400A)
                        NCR5380_write(C400_CONTROL_STATUS_REG, CSR_BASE);

                NCR5380_maybe_reset_bus(instance);


And PDMA works on I/O mapped 53C400A (HP C2502)!

# modprobe g_NCR5380 ncr_irq=7 ncr_addr=0x280 ncr_53c400a=1
[ 1799.939856] scsi host4: Generic NCR5380/NCR53C400 SCSI, io_port 0x280, n_io_port 16, base 0x0, irq 0, can_queue 16, cmd_per_lun 2, sg_tablesize 128, this_id 7, flags { NO_DMA_FIXUP }, options { AUTOPROBE_IRQ PSEUDO_DMA }
[ 1816.277018] scsi 4:0:1:0: Direct-Access     QUANTUM  LP240S GM240S01X 4.6  PQ: 0 ANSI: 2 CCS
[ 1897.899648] sd 4:0:1:0: Attached scsi generic sg1 type 0
[ 1897.917842] sd 4:0:1:0: [sdb] 479350 512-byte logical blocks: (245 MB/234 MiB)
[ 1897.920872] sd 4:0:1:0: [sdb] Write Protect is off
[ 1897.924744] sd 4:0:1:0: [sdb] Write cache: enabled, read cache: enabled, doesn't support DPO or FUA
[ 1897.967857]  sdb: sdb1
[ 1897.993822] sd 4:0:1:0: [sdb] Attached SCSI disk


Nice performance improvement (although it's slower than the memory-mapped
53C400):
# hdparm -t --direct /dev/sdb

/dev/sdb:
 Timing O_DIRECT disk reads:   2 MB in  3.99 seconds = 513.57 kB/sec


And it even fixed the IRQ:
# head /proc/interrupts
           CPU0
  0:     151228    XT-PIC  timer
  1:          9    XT-PIC  i8042
  2:          0    XT-PIC  cascade
  7:        115    XT-PIC  NCR5380
  8:          1    XT-PIC  rtc0
  9:          0    XT-PIC  uhci_hcd:usb1, uhci_hcd:usb2
 10:       3256    XT-PIC  eth0
 12:        136    XT-PIC  i8042
 14:       3833    XT-PIC  pata_via


-- 
Ondrej Zary

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

* Re: [PATCH 22/71] ncr5380: Eliminate selecting state
  2015-11-25 21:59       ` Ondrej Zary
@ 2015-11-26 10:23         ` Finn Thain
  2015-11-26 19:35           ` Ondrej Zary
  0 siblings, 1 reply; 268+ messages in thread
From: Finn Thain @ 2015-11-26 10:23 UTC (permalink / raw)
  To: Ondrej Zary
  Cc: James E.J. Bottomley, Michael Schmitz, linux-m68k, linux-scsi,
	linux-kernel


On Wed, 25 Nov 2015, Ondrej Zary wrote:

> On Wednesday 25 November 2015 04:17:09 Finn Thain wrote:
> > 
> > On Tue, 24 Nov 2015, Ondrej Zary wrote:
> > 
> > > 
> > > Bisecting slow module initialization pointed to this commit.
> > > 
> > > Before this commit (2 seconds):
> > > [   60.317374] scsi host2: Generic NCR5380/NCR53C400 SCSI, io_port 0x0, n_io_port 0, base 0xd8000, irq 0, can_queue 16, cmd_per_lun 2, sg_tablesize 128, this_id 7, flags { NCR53C400 }, USLEEP_POLL 3, USLEEP_SLEEP 50, options { AUTOPROBE_IRQ PSEUDO_DMA }
> > > [   60.780715] scsi 2:0:1:0: Direct-Access     QUANTUM  LP240S GM240S01X 4.6  PQ: 0 ANSI: 2 CCS
> > > [   62.606260] sd 2:0:1:0: Attached scsi generic sg1 type 0
> > > 
> > > 
> > > After this commit (22 seconds):
> > > [  137.511711] scsi host2: Generic NCR5380/NCR53C400 SCSI, io_port 0x0, n_io_port 0, base 0xd8000, irq 0, can_queue 16, cmd_per_lun 2, sg_tablesize 128, this_id 7, flags { NCR53C400 }, USLEEP_POLL 3, USLEEP_SLEEP 50, options { AUTOPROBE_IRQ PSEUDO_DMA }
> > > [  145.028532] clocksource: timekeeping watchdog: Marking clocksource 'tsc' as unstable because the skew is too large:
> > > [  145.029767] clocksource:                       'acpi_pm' wd_now: a49738 wd_last: f4da04 mask: ffffff
> > > [  145.029828] clocksource:                       'tsc' cs_now: 2ea624698e cs_last: 2c710aa17f mask: ffffffffffffffff
> > > [  145.032733] clocksource: Switched to clocksource acpi_pm
> > > [  145.236951] scsi 2:0:1:0: Direct-Access     QUANTUM  LP240S GM240S01X 4.6  PQ: 0 ANSI: 2 CCS
> > > [  159.959308] sd 2:0:1:0: Attached scsi generic sg1 type 0
> > > 
> > > 
> > 
> > This problem doesn't show up on my hardware, and I'd like to know where 
> > those 22 seconds are being spent. Would you please apply the entire series 
> > and add,
> > #define NDEBUG (NDEBUG_ARBITRATION | NDEBUG_SELECTION | NDEBUG_MAIN)
> > to the top of g_NCR5380.c and send me the messages logged during modprobe?
> 
> [  397.014581] scsi host2: Generic NCR5380/NCR53C400 SCSI, io_port 0x0, n_io_port 0, base 0xd8000, irq 0, can_queue 16, cmd_per_lun 2, sg_tablesize 128, this_id 7, flags { NO_DMA_FIXUP }, options { AUTOPROBE_IRQ PSEUDO_DMA }
> [  412.099695] STATUS_REG: 00
> BASR: 08
> ICR: 00
> MODE: 00
> [  412.103625] STATUS_REG: 00
> BASR: 08
> ICR: 00
> MODE: 00
> [  412.110503] scsi 2:0:1:0: Direct-Access     QUANTUM  LP240S GM240S01X 4.6  PQ: 0 ANSI: 2 CCS
> [  412.110892] STATUS_REG: 00
> BASR: 08
> ICR: 00
> MODE: 00
> [  412.114154] STATUS_REG: 00
> BASR: 08
> ICR: 00
> MODE: 00
> [  412.119733] STATUS_REG: 00
> BASR: 08
> ICR: 00
> MODE: 00
> [  427.198108] STATUS_REG: 00
> BASR: 08
> ICR: 00
> MODE: 00
> [  442.276586] STATUS_REG: 00
> BASR: 08
> ICR: 00
> MODE: 00
> [  457.354592] STATUS_REG: 00
> BASR: 08
> ICR: 00
> MODE: 00
> [  472.432999] STATUS_REG: 00
> BASR: 08
> ICR: 00
> MODE: 00
> [  487.513027] sd 2:0:1:0: Attached scsi generic sg1 type 0
> 
> 

I see that the delay increased from 22 seconds to 90 seconds. Perhaps that 
is because the remaining patches were applied.

Anyway, it seems to confirm that this delay comes from scanning the six 
unused SCSI bus IDs. Each one takes 15 seconds. Could be a five second 
timeout and three retries. It's hard to tell because the dsprintk() 
logging didn't show up. Can you try modprobe after,
# echo 1 > /sys/module/printk/parameters/ignore_loglevel
And maybe also,
# scsi_logging_level -sS7

It seems like the 53C400 chip doesn't arbitrate like a 53C80, but that 
doesn't make sense given it contains a 53C80 logic block. Perhaps some 
extra initialization is needed. Which card(s) are affected?

Aside from trying to figure out why the chip behaves oddly, we could also 
try to figure out whether the driver and its main loop is causing problems 
for other tasks i.e. timekeeping watchdog. Does this patch make any 
difference?

Index: linux/drivers/scsi/atari_NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/atari_NCR5380.c	2015-11-26 15:42:01.000000000 +1100
+++ linux/drivers/scsi/atari_NCR5380.c	2015-11-26 15:42:04.000000000 +1100
@@ -925,6 +925,7 @@ static void NCR5380_main(struct work_str
 		container_of(work, struct NCR5380_hostdata, main_task);
 	struct Scsi_Host *instance = hostdata->host;
 	struct scsi_cmnd *cmd;
+	unsigned long deadline = jiffies + msecs_to_jiffies(10);
 	int done;
 
 	/*
@@ -984,9 +985,12 @@ static void NCR5380_main(struct work_str
 			done = 0;
 		}
 		spin_unlock_irq(&hostdata->lock);
-		if (!done)
-			cond_resched();
-	} while (!done);
+		if (done || time_is_before_jiffies(deadline))
+			break;
+		cond_resched();
+	} while (1);
+	if (!done)
+		queue_work(hostdata->work_q, &hostdata->main_task);
 }
 
 
Index: linux/drivers/scsi/NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/NCR5380.c	2015-11-26 15:42:01.000000000 +1100
+++ linux/drivers/scsi/NCR5380.c	2015-11-26 15:42:04.000000000 +1100
@@ -817,6 +817,7 @@ static void NCR5380_main(struct work_str
 		container_of(work, struct NCR5380_hostdata, main_task);
 	struct Scsi_Host *instance = hostdata->host;
 	struct scsi_cmnd *cmd;
+	unsigned long deadline = jiffies + msecs_to_jiffies(10);
 	int done;
 
 	do {
@@ -860,9 +861,12 @@ static void NCR5380_main(struct work_str
 			done = 0;
 		}
 		spin_unlock_irq(&hostdata->lock);
-		if (!done)
-			cond_resched();
-	} while (!done);
+		if (done || time_is_before_jiffies(deadline))
+			break;
+		cond_resched();
+	} while (1);
+	if (!done)
+		queue_work(hostdata->work_q, &hostdata->main_task);
 }
 
 #ifndef DONT_USE_INTR

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

* Re: [PATCH 22/71] ncr5380: Eliminate selecting state
  2015-11-26 10:23         ` Finn Thain
@ 2015-11-26 19:35           ` Ondrej Zary
  2015-11-26 22:32             ` Finn Thain
  0 siblings, 1 reply; 268+ messages in thread
From: Ondrej Zary @ 2015-11-26 19:35 UTC (permalink / raw)
  To: Finn Thain
  Cc: James E.J. Bottomley, Michael Schmitz, linux-m68k, linux-scsi,
	linux-kernel

On Thursday 26 November 2015 11:23:01 Finn Thain wrote:
> 
> On Wed, 25 Nov 2015, Ondrej Zary wrote:
> 
> > On Wednesday 25 November 2015 04:17:09 Finn Thain wrote:
> > > 
> > > On Tue, 24 Nov 2015, Ondrej Zary wrote:
> > > 
> > > > 
> > > > Bisecting slow module initialization pointed to this commit.
> > > > 
> > > > Before this commit (2 seconds):
> > > > [   60.317374] scsi host2: Generic NCR5380/NCR53C400 SCSI, io_port 0x0, n_io_port 0, base 0xd8000, irq 0, can_queue 16, cmd_per_lun 2, sg_tablesize 128, this_id 7, flags { NCR53C400 }, USLEEP_POLL 3, USLEEP_SLEEP 50, options { AUTOPROBE_IRQ PSEUDO_DMA }
> > > > [   60.780715] scsi 2:0:1:0: Direct-Access     QUANTUM  LP240S GM240S01X 4.6  PQ: 0 ANSI: 2 CCS
> > > > [   62.606260] sd 2:0:1:0: Attached scsi generic sg1 type 0
> > > > 
> > > > 
> > > > After this commit (22 seconds):
> > > > [  137.511711] scsi host2: Generic NCR5380/NCR53C400 SCSI, io_port 0x0, n_io_port 0, base 0xd8000, irq 0, can_queue 16, cmd_per_lun 2, sg_tablesize 128, this_id 7, flags { NCR53C400 }, USLEEP_POLL 3, USLEEP_SLEEP 50, options { AUTOPROBE_IRQ PSEUDO_DMA }
> > > > [  145.028532] clocksource: timekeeping watchdog: Marking clocksource 'tsc' as unstable because the skew is too large:
> > > > [  145.029767] clocksource:                       'acpi_pm' wd_now: a49738 wd_last: f4da04 mask: ffffff
> > > > [  145.029828] clocksource:                       'tsc' cs_now: 2ea624698e cs_last: 2c710aa17f mask: ffffffffffffffff
> > > > [  145.032733] clocksource: Switched to clocksource acpi_pm
> > > > [  145.236951] scsi 2:0:1:0: Direct-Access     QUANTUM  LP240S GM240S01X 4.6  PQ: 0 ANSI: 2 CCS
> > > > [  159.959308] sd 2:0:1:0: Attached scsi generic sg1 type 0
> > > > 
> > > > 
> > > 
> > > This problem doesn't show up on my hardware, and I'd like to know where 
> > > those 22 seconds are being spent. Would you please apply the entire series 
> > > and add,
> > > #define NDEBUG (NDEBUG_ARBITRATION | NDEBUG_SELECTION | NDEBUG_MAIN)
> > > to the top of g_NCR5380.c and send me the messages logged during modprobe?
> > 
> > [  397.014581] scsi host2: Generic NCR5380/NCR53C400 SCSI, io_port 0x0, n_io_port 0, base 0xd8000, irq 0, can_queue 16, cmd_per_lun 2, sg_tablesize 128, this_id 7, flags { NO_DMA_FIXUP }, options { AUTOPROBE_IRQ PSEUDO_DMA }
> > [  412.099695] STATUS_REG: 00
> > BASR: 08
> > ICR: 00
> > MODE: 00
> > [  412.103625] STATUS_REG: 00
> > BASR: 08
> > ICR: 00
> > MODE: 00
> > [  412.110503] scsi 2:0:1:0: Direct-Access     QUANTUM  LP240S GM240S01X 4.6  PQ: 0 ANSI: 2 CCS
> > [  412.110892] STATUS_REG: 00
> > BASR: 08
> > ICR: 00
> > MODE: 00
> > [  412.114154] STATUS_REG: 00
> > BASR: 08
> > ICR: 00
> > MODE: 00
> > [  412.119733] STATUS_REG: 00
> > BASR: 08
> > ICR: 00
> > MODE: 00
> > [  427.198108] STATUS_REG: 00
> > BASR: 08
> > ICR: 00
> > MODE: 00
> > [  442.276586] STATUS_REG: 00
> > BASR: 08
> > ICR: 00
> > MODE: 00
> > [  457.354592] STATUS_REG: 00
> > BASR: 08
> > ICR: 00
> > MODE: 00
> > [  472.432999] STATUS_REG: 00
> > BASR: 08
> > ICR: 00
> > MODE: 00
> > [  487.513027] sd 2:0:1:0: Attached scsi generic sg1 type 0
> > 
> > 
> 
> I see that the delay increased from 22 seconds to 90 seconds. Perhaps that 
> is because the remaining patches were applied.

The remaining patches were not applied. The delay varies, probably depending
on the state of the external drive.

> Anyway, it seems to confirm that this delay comes from scanning the six 
> unused SCSI bus IDs. Each one takes 15 seconds. Could be a five second 
> timeout and three retries. It's hard to tell because the dsprintk() 
> logging didn't show up. Can you try modprobe after,
> # echo 1 > /sys/module/printk/parameters/ignore_loglevel
> And maybe also,
> # scsi_logging_level -sS7

[  156.014234] scsi host2: Generic NCR5380/NCR53C400 SCSI, io_port 0x0, n_io_port 0, base 0xd8000, irq 0, can_queue 16, cmd_per_lun 2, sg_tablesize 128, this_id 7, flags { NO_DMA_FIXUP }, options { AUTOPROBE_IRQ PSEUDO_DMA }
[  156.020369] scsi host2: scsi_scan_host_selected: <4294967295:4294967295:18446744073709551615>
[  156.020777] scsi 2:0:0:0: scsi scan: INQUIRY pass 1 length 36
[  156.022046] scsi host2: main: dequeued de045600
[  156.022109] STATUS_REG: 00
BASR: 00
ICR: 00
MODE: 00
[  156.022451] scsi host2: starting arbitration, id = 7
[  156.022740] scsi host2: won arbitration
[  156.022806] scsi host2: selecting target 0
[  171.097450] scsi host2: target did not respond within 250ms
[  171.097508] scsi host2: main: select complete
[  171.099554] scsi 2:0:0:0: scsi scan: INQUIRY failed with code 0x40000
[  171.103200] scsi 2:0:1:0: scsi scan: INQUIRY pass 1 length 36
[  171.105246] scsi host2: main: dequeued df6b9f00
[  171.105350] STATUS_REG: 00
BASR: 08
ICR: 00
MODE: 00
[  171.105664] scsi host2: starting arbitration, id = 7
[  171.105752] scsi host2: won arbitration
[  171.105822] scsi host2: selecting target 1
[  171.105977] scsi host2: target 1 selected, going into MESSAGE OUT phase.
[  171.106042] scsi host2: nexus established.
[  171.106093] scsi host2: main: select complete
[  171.106145] scsi host2: main: performing information transfer
[  171.108531] scsi 2:0:1:0: scsi scan: INQUIRY successful with code 0x0
[  171.108639] scsi 2:0:1:0: scsi scan: INQUIRY pass 2 length 130
[  171.109401] scsi host2: main: dequeued df6b9f00
[  171.109485] STATUS_REG: 00
BASR: 08
ICR: 00
MODE: 00
[  171.109779] scsi host2: starting arbitration, id = 7
[  171.109878] scsi host2: won arbitration
[  171.109954] scsi host2: selecting target 1
[  171.110112] scsi host2: target 1 selected, going into MESSAGE OUT phase.
[  171.110181] scsi host2: nexus established.
[  171.110236] scsi host2: main: select complete
[  171.110286] scsi host2: main: performing information transfer
[  171.114811] scsi 2:0:1:0: scsi scan: INQUIRY successful with code 0x0
[  171.114928] scsi 2:0:1:0: Direct-Access     QUANTUM  LP240S GM240S01X 4.6  PQ: 0 ANSI: 2 CCS
[  171.115011] scsi target2:0:1: scsi scan: Sequential scan
[  171.115856] scsi 2:0:1:1: scsi scan: INQUIRY pass 1 length 36
[  171.116008] scsi host2: main: dequeued df6b9800
[  171.116039] STATUS_REG: 00
BASR: 08
ICR: 00
MODE: 00
[  171.116736] scsi host2: starting arbitration, id = 7
[  171.116843] scsi host2: won arbitration
[  171.116898] scsi host2: selecting target 1
[  171.117117] scsi host2: target 1 selected, going into MESSAGE OUT phase.
[  171.117182] scsi host2: nexus established.
[  171.117234] scsi host2: main: select complete
[  171.117287] scsi host2: main: performing information transfer
[  171.119674] scsi 2:0:1:1: scsi scan: INQUIRY successful with code 0x0
[  171.119781] scsi 2:0:1:1: scsi scan: INQUIRY pass 2 length 130
[  171.119898] scsi host2: main: dequeued df6b9800
[  171.119962] STATUS_REG: 00
BASR: 08
ICR: 00
MODE: 00
[  171.121426] scsi host2: starting arbitration, id = 7
[  171.121537] scsi host2: won arbitration
[  171.121592] scsi host2: selecting target 1
[  171.121766] scsi host2: target 1 selected, going into MESSAGE OUT phase.
[  171.121834] scsi host2: nexus established.
[  171.121889] scsi host2: main: select complete
[  171.121940] scsi host2: main: performing information transfer
[  171.126361] scsi 2:0:1:1: scsi scan: INQUIRY successful with code 0x0
[  171.126470] scsi 2:0:1:1: scsi scan: peripheral qualifier of 3, device not added
[  171.127735] scsi 2:0:2:0: scsi scan: INQUIRY pass 1 length 36
[  171.127920] scsi host2: main: dequeued df6b9800
[  171.127982] STATUS_REG: 00
BASR: 08
ICR: 00
MODE: 00
[  171.128648] scsi host2: starting arbitration, id = 7
[  171.128754] scsi host2: won arbitration
[  171.128811] scsi host2: selecting target 2
[  186.203734] scsi host2: target did not respond within 250ms
[  186.203794] scsi host2: main: select complete
[  186.205355] scsi 2:0:2:0: scsi scan: INQUIRY failed with code 0x40000
[  186.208989] scsi 2:0:3:0: scsi scan: INQUIRY pass 1 length 36
[  186.209178] scsi host2: main: dequeued df6b9f00
[  186.209242] STATUS_REG: 00
BASR: 08
ICR: 00
MODE: 00
[  186.209570] scsi host2: starting arbitration, id = 7
[  186.209660] scsi host2: won arbitration
[  186.209731] scsi host2: selecting target 3
[  201.284666] scsi host2: target did not respond within 250ms
[  201.284726] scsi host2: main: select complete
[  201.286193] scsi 2:0:3:0: scsi scan: INQUIRY failed with code 0x40000
[  201.287455] scsi 2:0:4:0: scsi scan: INQUIRY pass 1 length 36
[  201.287609] scsi host2: main: dequeued df6b9900
[  201.287673] STATUS_REG: 00
BASR: 08
ICR: 00
MODE: 00
[  201.287973] scsi host2: starting arbitration, id = 7
[  201.288766] scsi host2: won arbitration
[  201.288855] scsi host2: selecting target 4
[  216.363793] scsi host2: target did not respond within 250ms
[  216.363853] scsi host2: main: select complete
[  216.363947] scsi 2:0:4:0: scsi scan: INQUIRY failed with code 0x40000
[  216.366469] scsi 2:0:5:0: scsi scan: INQUIRY pass 1 length 36
[  216.366633] scsi host2: main: dequeued df6b9f00
[  216.366696] STATUS_REG: 00
BASR: 08
ICR: 00
MODE: 00
[  216.366997] scsi host2: starting arbitration, id = 7
[  216.367153] scsi host2: won arbitration
[  216.367208] scsi host2: selecting target 5
[  231.442079] scsi host2: target did not respond within 250ms
[  231.442136] scsi host2: main: select complete
[  231.442214] scsi 2:0:5:0: scsi scan: INQUIRY failed with code 0x40000
[  231.445050] scsi 2:0:6:0: scsi scan: INQUIRY pass 1 length 36
[  231.445329] scsi host2: main: dequeued df6b9c00
[  231.445392] STATUS_REG: 00
BASR: 08
ICR: 00
MODE: 00
[  231.445682] scsi host2: starting arbitration, id = 7
[  231.445784] scsi host2: won arbitration
[  231.445855] scsi host2: selecting target 6
[  246.521110] scsi host2: target did not respond within 250ms
[  246.521171] scsi host2: main: select complete
[  246.521253] scsi 2:0:6:0: scsi scan: INQUIRY failed with code 0x40000
[  246.525098] sd 2:0:1:0: Attached scsi generic sg1 type 0


> It seems like the 53C400 chip doesn't arbitrate like a 53C80, but that 
> doesn't make sense given it contains a 53C80 logic block. Perhaps some 
> extra initialization is needed. Which card(s) are affected?

All of them: HP C2502 (53C400A), Canon FG2-5202 (53C400) and DTCT-436P.
 
> Aside from trying to figure out why the chip behaves oddly, we could also 
> try to figure out whether the driver and its main loop is causing problems 
> for other tasks i.e. timekeeping watchdog. Does this patch make any 
> difference?

The timekeeping warning does not appear when all 71 patches are applied.
Reverse-bisected it - the warning disappears after:
[PATCH 50/71] ncr5380: Change instance->host_lock to hostdata->lock

-- 
Ondrej Zary

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

* Re: [PATCH 22/71] ncr5380: Eliminate selecting state
  2015-11-26 19:35           ` Ondrej Zary
@ 2015-11-26 22:32             ` Finn Thain
  2015-11-28 23:13               ` Ondrej Zary
  2015-11-29  9:27               ` Geert Uytterhoeven
  0 siblings, 2 replies; 268+ messages in thread
From: Finn Thain @ 2015-11-26 22:32 UTC (permalink / raw)
  To: Ondrej Zary
  Cc: James E.J. Bottomley, Michael Schmitz, linux-m68k, linux-scsi,
	linux-kernel


On Thu, 26 Nov 2015, Ondrej Zary wrote:

> 
> [  156.014234] scsi host2: Generic NCR5380/NCR53C400 SCSI, io_port 0x0, n_io_port 0, base 0xd8000, irq 0, can_queue 16, cmd_per_lun 2, sg_tablesize 128, this_id 7, flags { NO_DMA_FIXUP }, options { AUTOPROBE_IRQ PSEUDO_DMA }
> [  156.020369] scsi host2: scsi_scan_host_selected: <4294967295:4294967295:18446744073709551615>
> [  156.020777] scsi 2:0:0:0: scsi scan: INQUIRY pass 1 length 36
> [  156.022046] scsi host2: main: dequeued de045600
> [  156.022109] STATUS_REG: 00
> BASR: 00
> ICR: 00
> MODE: 00
> [  156.022451] scsi host2: starting arbitration, id = 7
> [  156.022740] scsi host2: won arbitration
> [  156.022806] scsi host2: selecting target 0
> [  171.097450] scsi host2: target did not respond within 250ms
> [  171.097508] scsi host2: main: select complete
> [  171.099554] scsi 2:0:0:0: scsi scan: INQUIRY failed with code 0x40000

This is very helpful, thanks.

The problem has to be this:

        err = NCR5380_poll_politely(instance, STATUS_REG, SR_BSY, SR_BSY,
                                    msecs_to_jiffies(250));

which would suggest a problem with the busy wait loop. It seems that 5380 
register accesses are much more expensive on PC than the platforms I've 
tested.

> [  171.103200] scsi 2:0:1:0: scsi scan: INQUIRY pass 1 length 36
> [  171.105246] scsi host2: main: dequeued df6b9f00
> [  171.105350] STATUS_REG: 00
> BASR: 08
> ICR: 00
> MODE: 00
> [  171.105664] scsi host2: starting arbitration, id = 7
> [  171.105752] scsi host2: won arbitration
> [  171.105822] scsi host2: selecting target 1
> [  171.105977] scsi host2: target 1 selected, going into MESSAGE OUT phase.
> [  171.106042] scsi host2: nexus established.
> [  171.106093] scsi host2: main: select complete
> [  171.106145] scsi host2: main: performing information transfer
> [  171.108531] scsi 2:0:1:0: scsi scan: INQUIRY successful with code 0x0
> [  171.108639] scsi 2:0:1:0: scsi scan: INQUIRY pass 2 length 130
> [  171.109401] scsi host2: main: dequeued df6b9f00
> [  171.109485] STATUS_REG: 00
> BASR: 08
> ICR: 00
> MODE: 00
> [  171.109779] scsi host2: starting arbitration, id = 7
> [  171.109878] scsi host2: won arbitration
> [  171.109954] scsi host2: selecting target 1
> [  171.110112] scsi host2: target 1 selected, going into MESSAGE OUT phase.
> [  171.110181] scsi host2: nexus established.
> [  171.110236] scsi host2: main: select complete
> [  171.110286] scsi host2: main: performing information transfer
> [  171.114811] scsi 2:0:1:0: scsi scan: INQUIRY successful with code 0x0
> [  171.114928] scsi 2:0:1:0: Direct-Access     QUANTUM  LP240S GM240S01X 4.6  PQ: 0 ANSI: 2 CCS
> [  171.115011] scsi target2:0:1: scsi scan: Sequential scan
> [  171.115856] scsi 2:0:1:1: scsi scan: INQUIRY pass 1 length 36
> [  171.116008] scsi host2: main: dequeued df6b9800
> [  171.116039] STATUS_REG: 00
> BASR: 08
> ICR: 00
> MODE: 00
> [  171.116736] scsi host2: starting arbitration, id = 7
> [  171.116843] scsi host2: won arbitration
> [  171.116898] scsi host2: selecting target 1
> [  171.117117] scsi host2: target 1 selected, going into MESSAGE OUT phase.
> [  171.117182] scsi host2: nexus established.
> [  171.117234] scsi host2: main: select complete
> [  171.117287] scsi host2: main: performing information transfer
> [  171.119674] scsi 2:0:1:1: scsi scan: INQUIRY successful with code 0x0
> [  171.119781] scsi 2:0:1:1: scsi scan: INQUIRY pass 2 length 130
> [  171.119898] scsi host2: main: dequeued df6b9800
> [  171.119962] STATUS_REG: 00
> BASR: 08
> ICR: 00
> MODE: 00
> [  171.121426] scsi host2: starting arbitration, id = 7
> [  171.121537] scsi host2: won arbitration
> [  171.121592] scsi host2: selecting target 1
> [  171.121766] scsi host2: target 1 selected, going into MESSAGE OUT phase.
> [  171.121834] scsi host2: nexus established.
> [  171.121889] scsi host2: main: select complete
> [  171.121940] scsi host2: main: performing information transfer
> [  171.126361] scsi 2:0:1:1: scsi scan: INQUIRY successful with code 0x0
> [  171.126470] scsi 2:0:1:1: scsi scan: peripheral qualifier of 3, device not added
> [  171.127735] scsi 2:0:2:0: scsi scan: INQUIRY pass 1 length 36
> [  171.127920] scsi host2: main: dequeued df6b9800
> [  171.127982] STATUS_REG: 00
> BASR: 08
> ICR: 00
> MODE: 00
> [  171.128648] scsi host2: starting arbitration, id = 7
> [  171.128754] scsi host2: won arbitration
> [  171.128811] scsi host2: selecting target 2
> [  186.203734] scsi host2: target did not respond within 250ms
> [  186.203794] scsi host2: main: select complete
> [  186.205355] scsi 2:0:2:0: scsi scan: INQUIRY failed with code 0x40000
> [  186.208989] scsi 2:0:3:0: scsi scan: INQUIRY pass 1 length 36
> [  186.209178] scsi host2: main: dequeued df6b9f00
> [  186.209242] STATUS_REG: 00
> BASR: 08
> ICR: 00
> MODE: 00
> [  186.209570] scsi host2: starting arbitration, id = 7
> [  186.209660] scsi host2: won arbitration
> [  186.209731] scsi host2: selecting target 3
> [  201.284666] scsi host2: target did not respond within 250ms
> [  201.284726] scsi host2: main: select complete
> [  201.286193] scsi 2:0:3:0: scsi scan: INQUIRY failed with code 0x40000
> [  201.287455] scsi 2:0:4:0: scsi scan: INQUIRY pass 1 length 36
> [  201.287609] scsi host2: main: dequeued df6b9900
> [  201.287673] STATUS_REG: 00
> BASR: 08
> ICR: 00
> MODE: 00
> [  201.287973] scsi host2: starting arbitration, id = 7
> [  201.288766] scsi host2: won arbitration
> [  201.288855] scsi host2: selecting target 4
> [  216.363793] scsi host2: target did not respond within 250ms
> [  216.363853] scsi host2: main: select complete
> [  216.363947] scsi 2:0:4:0: scsi scan: INQUIRY failed with code 0x40000
> [  216.366469] scsi 2:0:5:0: scsi scan: INQUIRY pass 1 length 36
> [  216.366633] scsi host2: main: dequeued df6b9f00
> [  216.366696] STATUS_REG: 00
> BASR: 08
> ICR: 00
> MODE: 00
> [  216.366997] scsi host2: starting arbitration, id = 7
> [  216.367153] scsi host2: won arbitration
> [  216.367208] scsi host2: selecting target 5
> [  231.442079] scsi host2: target did not respond within 250ms
> [  231.442136] scsi host2: main: select complete
> [  231.442214] scsi 2:0:5:0: scsi scan: INQUIRY failed with code 0x40000
> [  231.445050] scsi 2:0:6:0: scsi scan: INQUIRY pass 1 length 36
> [  231.445329] scsi host2: main: dequeued df6b9c00
> [  231.445392] STATUS_REG: 00
> BASR: 08
> ICR: 00
> MODE: 00
> [  231.445682] scsi host2: starting arbitration, id = 7
> [  231.445784] scsi host2: won arbitration
> [  231.445855] scsi host2: selecting target 6
> [  246.521110] scsi host2: target did not respond within 250ms
> [  246.521171] scsi host2: main: select complete
> [  246.521253] scsi 2:0:6:0: scsi scan: INQUIRY failed with code 0x40000
> [  246.525098] sd 2:0:1:0: Attached scsi generic sg1 type 0
> 
> 
> > [...] Which card(s) are affected?
> 
> All of them: HP C2502 (53C400A), Canon FG2-5202 (53C400) and DTCT-436P.
>  

OK.

> > Aside from trying to figure out why the chip behaves oddly, we could also 
> > try to figure out whether the driver and its main loop is causing problems 
> > for other tasks i.e. timekeeping watchdog. Does this patch make any 
> > difference?
> 
> The timekeeping warning does not appear when all 71 patches are applied.
> Reverse-bisected it - the warning disappears after:
> [PATCH 50/71] ncr5380: Change instance->host_lock to hostdata->lock
> 

Makes sense. I think that this should solve the problem:

Index: linux/drivers/scsi/NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/NCR5380.c	2015-11-27 09:21:40.000000000 +1100
+++ linux/drivers/scsi/NCR5380.c	2015-11-27 09:25:36.000000000 +1100
@@ -230,7 +230,7 @@ static int NCR5380_poll_politely2(struct
 	unsigned long n;
 
 	/* Busy-wait for up to 1 jiffy */
-	n = loops_per_jiffy;
+	n = 1 + loops_per_jiffy / 10;
 	do {
 		if ((NCR5380_read(reg1) & bit1) == val1)
 			return 0;

-- 

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

* Re: [PATCH 22/71] ncr5380: Eliminate selecting state
  2015-11-26 22:32             ` Finn Thain
@ 2015-11-28 23:13               ` Ondrej Zary
  2015-11-29  0:46                 ` Finn Thain
  2015-11-29  9:27               ` Geert Uytterhoeven
  1 sibling, 1 reply; 268+ messages in thread
From: Ondrej Zary @ 2015-11-28 23:13 UTC (permalink / raw)
  To: Finn Thain
  Cc: James E.J. Bottomley, Michael Schmitz, linux-m68k, linux-scsi,
	linux-kernel

On Thursday 26 November 2015 23:32:46 Finn Thain wrote:
> 
> On Thu, 26 Nov 2015, Ondrej Zary wrote:
> 
> > 
> > [  156.014234] scsi host2: Generic NCR5380/NCR53C400 SCSI, io_port 0x0, n_io_port 0, base 0xd8000, irq 0, can_queue 16, cmd_per_lun 2, sg_tablesize 128, this_id 7, flags { NO_DMA_FIXUP }, options { AUTOPROBE_IRQ PSEUDO_DMA }
> > [  156.020369] scsi host2: scsi_scan_host_selected: <4294967295:4294967295:18446744073709551615>
> > [  156.020777] scsi 2:0:0:0: scsi scan: INQUIRY pass 1 length 36
> > [  156.022046] scsi host2: main: dequeued de045600
> > [  156.022109] STATUS_REG: 00
> > BASR: 00
> > ICR: 00
> > MODE: 00
> > [  156.022451] scsi host2: starting arbitration, id = 7
> > [  156.022740] scsi host2: won arbitration
> > [  156.022806] scsi host2: selecting target 0
> > [  171.097450] scsi host2: target did not respond within 250ms
> > [  171.097508] scsi host2: main: select complete
> > [  171.099554] scsi 2:0:0:0: scsi scan: INQUIRY failed with code 0x40000
> 
> This is very helpful, thanks.
> 
> The problem has to be this:
> 
>         err = NCR5380_poll_politely(instance, STATUS_REG, SR_BSY, SR_BSY,
>                                     msecs_to_jiffies(250));
> 
> which would suggest a problem with the busy wait loop. It seems that 5380 
> register accesses are much more expensive on PC than the platforms I've 
> tested.
> 
> > [  171.103200] scsi 2:0:1:0: scsi scan: INQUIRY pass 1 length 36
> > [  171.105246] scsi host2: main: dequeued df6b9f00
> > [  171.105350] STATUS_REG: 00
> > BASR: 08
> > ICR: 00
> > MODE: 00
> > [  171.105664] scsi host2: starting arbitration, id = 7
> > [  171.105752] scsi host2: won arbitration
> > [  171.105822] scsi host2: selecting target 1
> > [  171.105977] scsi host2: target 1 selected, going into MESSAGE OUT phase.
> > [  171.106042] scsi host2: nexus established.
> > [  171.106093] scsi host2: main: select complete
> > [  171.106145] scsi host2: main: performing information transfer
> > [  171.108531] scsi 2:0:1:0: scsi scan: INQUIRY successful with code 0x0
> > [  171.108639] scsi 2:0:1:0: scsi scan: INQUIRY pass 2 length 130
> > [  171.109401] scsi host2: main: dequeued df6b9f00
> > [  171.109485] STATUS_REG: 00
> > BASR: 08
> > ICR: 00
> > MODE: 00
> > [  171.109779] scsi host2: starting arbitration, id = 7
> > [  171.109878] scsi host2: won arbitration
> > [  171.109954] scsi host2: selecting target 1
> > [  171.110112] scsi host2: target 1 selected, going into MESSAGE OUT phase.
> > [  171.110181] scsi host2: nexus established.
> > [  171.110236] scsi host2: main: select complete
> > [  171.110286] scsi host2: main: performing information transfer
> > [  171.114811] scsi 2:0:1:0: scsi scan: INQUIRY successful with code 0x0
> > [  171.114928] scsi 2:0:1:0: Direct-Access     QUANTUM  LP240S GM240S01X 4.6  PQ: 0 ANSI: 2 CCS
> > [  171.115011] scsi target2:0:1: scsi scan: Sequential scan
> > [  171.115856] scsi 2:0:1:1: scsi scan: INQUIRY pass 1 length 36
> > [  171.116008] scsi host2: main: dequeued df6b9800
> > [  171.116039] STATUS_REG: 00
> > BASR: 08
> > ICR: 00
> > MODE: 00
> > [  171.116736] scsi host2: starting arbitration, id = 7
> > [  171.116843] scsi host2: won arbitration
> > [  171.116898] scsi host2: selecting target 1
> > [  171.117117] scsi host2: target 1 selected, going into MESSAGE OUT phase.
> > [  171.117182] scsi host2: nexus established.
> > [  171.117234] scsi host2: main: select complete
> > [  171.117287] scsi host2: main: performing information transfer
> > [  171.119674] scsi 2:0:1:1: scsi scan: INQUIRY successful with code 0x0
> > [  171.119781] scsi 2:0:1:1: scsi scan: INQUIRY pass 2 length 130
> > [  171.119898] scsi host2: main: dequeued df6b9800
> > [  171.119962] STATUS_REG: 00
> > BASR: 08
> > ICR: 00
> > MODE: 00
> > [  171.121426] scsi host2: starting arbitration, id = 7
> > [  171.121537] scsi host2: won arbitration
> > [  171.121592] scsi host2: selecting target 1
> > [  171.121766] scsi host2: target 1 selected, going into MESSAGE OUT phase.
> > [  171.121834] scsi host2: nexus established.
> > [  171.121889] scsi host2: main: select complete
> > [  171.121940] scsi host2: main: performing information transfer
> > [  171.126361] scsi 2:0:1:1: scsi scan: INQUIRY successful with code 0x0
> > [  171.126470] scsi 2:0:1:1: scsi scan: peripheral qualifier of 3, device not added
> > [  171.127735] scsi 2:0:2:0: scsi scan: INQUIRY pass 1 length 36
> > [  171.127920] scsi host2: main: dequeued df6b9800
> > [  171.127982] STATUS_REG: 00
> > BASR: 08
> > ICR: 00
> > MODE: 00
> > [  171.128648] scsi host2: starting arbitration, id = 7
> > [  171.128754] scsi host2: won arbitration
> > [  171.128811] scsi host2: selecting target 2
> > [  186.203734] scsi host2: target did not respond within 250ms
> > [  186.203794] scsi host2: main: select complete
> > [  186.205355] scsi 2:0:2:0: scsi scan: INQUIRY failed with code 0x40000
> > [  186.208989] scsi 2:0:3:0: scsi scan: INQUIRY pass 1 length 36
> > [  186.209178] scsi host2: main: dequeued df6b9f00
> > [  186.209242] STATUS_REG: 00
> > BASR: 08
> > ICR: 00
> > MODE: 00
> > [  186.209570] scsi host2: starting arbitration, id = 7
> > [  186.209660] scsi host2: won arbitration
> > [  186.209731] scsi host2: selecting target 3
> > [  201.284666] scsi host2: target did not respond within 250ms
> > [  201.284726] scsi host2: main: select complete
> > [  201.286193] scsi 2:0:3:0: scsi scan: INQUIRY failed with code 0x40000
> > [  201.287455] scsi 2:0:4:0: scsi scan: INQUIRY pass 1 length 36
> > [  201.287609] scsi host2: main: dequeued df6b9900
> > [  201.287673] STATUS_REG: 00
> > BASR: 08
> > ICR: 00
> > MODE: 00
> > [  201.287973] scsi host2: starting arbitration, id = 7
> > [  201.288766] scsi host2: won arbitration
> > [  201.288855] scsi host2: selecting target 4
> > [  216.363793] scsi host2: target did not respond within 250ms
> > [  216.363853] scsi host2: main: select complete
> > [  216.363947] scsi 2:0:4:0: scsi scan: INQUIRY failed with code 0x40000
> > [  216.366469] scsi 2:0:5:0: scsi scan: INQUIRY pass 1 length 36
> > [  216.366633] scsi host2: main: dequeued df6b9f00
> > [  216.366696] STATUS_REG: 00
> > BASR: 08
> > ICR: 00
> > MODE: 00
> > [  216.366997] scsi host2: starting arbitration, id = 7
> > [  216.367153] scsi host2: won arbitration
> > [  216.367208] scsi host2: selecting target 5
> > [  231.442079] scsi host2: target did not respond within 250ms
> > [  231.442136] scsi host2: main: select complete
> > [  231.442214] scsi 2:0:5:0: scsi scan: INQUIRY failed with code 0x40000
> > [  231.445050] scsi 2:0:6:0: scsi scan: INQUIRY pass 1 length 36
> > [  231.445329] scsi host2: main: dequeued df6b9c00
> > [  231.445392] STATUS_REG: 00
> > BASR: 08
> > ICR: 00
> > MODE: 00
> > [  231.445682] scsi host2: starting arbitration, id = 7
> > [  231.445784] scsi host2: won arbitration
> > [  231.445855] scsi host2: selecting target 6
> > [  246.521110] scsi host2: target did not respond within 250ms
> > [  246.521171] scsi host2: main: select complete
> > [  246.521253] scsi 2:0:6:0: scsi scan: INQUIRY failed with code 0x40000
> > [  246.525098] sd 2:0:1:0: Attached scsi generic sg1 type 0
> > 
> > 
> > > [...] Which card(s) are affected?
> > 
> > All of them: HP C2502 (53C400A), Canon FG2-5202 (53C400) and DTCT-436P.
> >  
> 
> OK.
> 
> > > Aside from trying to figure out why the chip behaves oddly, we could also 
> > > try to figure out whether the driver and its main loop is causing problems 
> > > for other tasks i.e. timekeeping watchdog. Does this patch make any 
> > > difference?
> > 
> > The timekeeping warning does not appear when all 71 patches are applied.
> > Reverse-bisected it - the warning disappears after:
> > [PATCH 50/71] ncr5380: Change instance->host_lock to hostdata->lock
> > 
> 
> Makes sense. I think that this should solve the problem:

Yes, it does!

[   48.119367] scsi host2: Generic NCR5380/NCR53C400 SCSI, io_port 0x0, n_io_port 0, base 0xd8000, irq 0, can_queue 16, cmd_per_lun 2, sg_tablesize 128, this_id 7, flags { NO_DMA_FIXUP }, options { AUTOPROBE_IRQ PSEUDO_DMA }
[   49.715388] scsi 2:0:1:0: Direct-Access     QUANTUM  LP240S GM240S01X 4.6  PQ: 0 ANSI: 2 CCS
[   57.653737] sd 2:0:1:0: Attached scsi generic sg1 type 0
[   57.672524] sd 2:0:1:0: [sdb] 479350 512-byte logical blocks: (245 MB/234 MiB)
[   57.675632] sd 2:0:1:0: [sdb] Write Protect is off
[   57.679534] sd 2:0:1:0: [sdb] Write cache: enabled, read cache: enabled, doesn't support DPO or FUA
[   57.724617]  sdb: sdb1
[   57.741620] sd 2:0:1:0: [sdb] Attached SCSI disk

-- 
Ondrej Zary

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

* Re: [PATCH 22/71] ncr5380: Eliminate selecting state
  2015-11-28 23:13               ` Ondrej Zary
@ 2015-11-29  0:46                 ` Finn Thain
  2015-11-29  9:09                   ` Ondrej Zary
  0 siblings, 1 reply; 268+ messages in thread
From: Finn Thain @ 2015-11-29  0:46 UTC (permalink / raw)
  To: Ondrej Zary
  Cc: James E.J. Bottomley, Michael Schmitz, linux-m68k, linux-scsi,
	linux-kernel


On Sun, 29 Nov 2015, Ondrej Zary wrote:

> > [...] I think that this should solve the problem:
> 
> Yes, it does!
> 
> [   48.119367] scsi host2: Generic NCR5380/NCR53C400 SCSI, io_port 0x0, n_io_port 0, base 0xd8000, irq 0, can_queue 16, cmd_per_lun 2, sg_tablesize 128, this_id 7, flags { NO_DMA_FIXUP }, options { AUTOPROBE_IRQ PSEUDO_DMA }
> [   49.715388] scsi 2:0:1:0: Direct-Access     QUANTUM  LP240S GM240S01X 4.6  PQ: 0 ANSI: 2 CCS

That still takes about 1.6 seconds to scan a vacant bus ID. It should be 
more like 0.25 seconds. Did you have the entire patch series applied?

The code presently in mainline spins for 500 iterations in the relevant 
busy-wait loop, with the comment, "8uS a cycle for the cpu access". That 
doesn't help me much. Does that refer to an ISA bus cycle? Or one 
iteration of the loop? Electrical conductance?

If we knew how many loops_per_jiffy your machine gets, and your CONFIG_HZ 
value, we could figure out how long a chip register access takes (which 
might be 8 us).

I'll try to figure out a similar timing for my Domex PCI card to see if 
there is some sort of compromise to be found.

-- 

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

* Re: [PATCH 22/71] ncr5380: Eliminate selecting state
  2015-11-29  0:46                 ` Finn Thain
@ 2015-11-29  9:09                   ` Ondrej Zary
  0 siblings, 0 replies; 268+ messages in thread
From: Ondrej Zary @ 2015-11-29  9:09 UTC (permalink / raw)
  To: Finn Thain
  Cc: James E.J. Bottomley, Michael Schmitz, linux-m68k, linux-scsi,
	linux-kernel

On Sunday 29 November 2015 01:46:03 Finn Thain wrote:
> 
> On Sun, 29 Nov 2015, Ondrej Zary wrote:
> 
> > > [...] I think that this should solve the problem:
> > 
> > Yes, it does!
> > 
> > [   48.119367] scsi host2: Generic NCR5380/NCR53C400 SCSI, io_port 0x0, n_io_port 0, base 0xd8000, irq 0, can_queue 16, cmd_per_lun 2, sg_tablesize 128, this_id 7, flags { NO_DMA_FIXUP }, options { AUTOPROBE_IRQ PSEUDO_DMA }
> > [   49.715388] scsi 2:0:1:0: Direct-Access     QUANTUM  LP240S GM240S01X 4.6  PQ: 0 ANSI: 2 CCS
> 
> That still takes about 1.6 seconds to scan a vacant bus ID. It should be 
> more like 0.25 seconds. Did you have the entire patch series applied?
> 
> The code presently in mainline spins for 500 iterations in the relevant 
> busy-wait loop, with the comment, "8uS a cycle for the cpu access". That 
> doesn't help me much. Does that refer to an ISA bus cycle? Or one 
> iteration of the loop? Electrical conductance?
> 
> If we knew how many loops_per_jiffy your machine gets, and your CONFIG_HZ 
> value, we could figure out how long a chip register access takes (which 
> might be 8 us).

loops_per_jiffy=4797252
CONFIG_HZ=250

# cat /proc/cpuinfo
processor       : 0
vendor_id       : GenuineIntel
cpu family      : 6
model           : 11
model name      : Intel(R) Celeron(TM) CPU                1200MHz
stepping        : 1
microcode       : 0x1c
cpu MHz         : 1199.313
cache size      : 256 KB
physical id     : 0
siblings        : 1
core id         : 0
cpu cores       : 1
apicid          : 0
initial apicid  : 0
fdiv_bug        : no
f00f_bug        : no
coma_bug        : no
fpu             : yes
fpu_exception   : yes
cpuid level     : 2
wp              : yes
flags           : fpu vme de pse tsc msr pae mce cx8 sep mtrr pge mca cmov pse36 mmx fxsr sse
bugs            :
bogomips        : 2398.62
clflush size    : 32
cache_alignment : 32
address sizes   : 36 bits physical, 32 bits virtual
power management:


# cat iotest.c
#include <stdio.h>
#include <sys/io.h>

int main(void) {
        if (iopl(3)) {
                perror("iopl");
                return 1;
        }
        for (int i = 0; i < 10000000; i++)
                inb(0x280);
        return 0;
}

# cc --std=c99 iotest.c -o iotest
# time ./iotest

real    0m16.938s
user    0m16.932s
sys     0m0.000s

outb() instead of inb():
# time ./iotest

real    0m17.210s
user    0m17.204s
sys     0m0.000s


> I'll try to figure out a similar timing for my Domex PCI card to see if 
> there is some sort of compromise to be found.


-- 
Ondrej Zary

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

* Re: [PATCH 22/71] ncr5380: Eliminate selecting state
  2015-11-26 22:32             ` Finn Thain
  2015-11-28 23:13               ` Ondrej Zary
@ 2015-11-29  9:27               ` Geert Uytterhoeven
  2015-11-29 10:25                 ` Finn Thain
  1 sibling, 1 reply; 268+ messages in thread
From: Geert Uytterhoeven @ 2015-11-29  9:27 UTC (permalink / raw)
  To: Finn Thain
  Cc: Ondrej Zary, James E.J. Bottomley, Michael Schmitz, Linux/m68k,
	scsi, linux-kernel

Hi Finn,

On Thu, Nov 26, 2015 at 11:32 PM, Finn Thain <fthain@telegraphics.com.au> wrote:
>> The timekeeping warning does not appear when all 71 patches are applied.
>> Reverse-bisected it - the warning disappears after:
>> [PATCH 50/71] ncr5380: Change instance->host_lock to hostdata->lock
>>
>
> Makes sense. I think that this should solve the problem:
>
> Index: linux/drivers/scsi/NCR5380.c
> ===================================================================
> --- linux.orig/drivers/scsi/NCR5380.c   2015-11-27 09:21:40.000000000 +1100
> +++ linux/drivers/scsi/NCR5380.c        2015-11-27 09:25:36.000000000 +1100
> @@ -230,7 +230,7 @@ static int NCR5380_poll_politely2(struct
>         unsigned long n;
>
>         /* Busy-wait for up to 1 jiffy */
> -       n = loops_per_jiffy;
> +       n = 1 + loops_per_jiffy / 10;
>         do {
>                 if ((NCR5380_read(reg1) & bit1) == val1)
>                         return 0;

This still heavily depends on the processing time spent in NCR5380_read().
You should never use a value derived from loops_per_jiffy for a non-empty loop,
as it may take much longer. Always compare with an maximum end time instead.

E.g.:

        end = jiffies + 2;        /* 1 jiffie + 1 safeguard */
        do {
                 if ((NCR5380_read(reg1) & bit1) == val1)
                         return 0;
                 cpu_relax();
        } while (time_before(jiffies, end);

And a similar loop for "Busy-wait for up to 20 ms".

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] 268+ messages in thread

* [RFC PATCH 73/71] ncr5380: Use runtime register mapping
  2015-11-18  8:34 ` Finn Thain
                   ` (73 preceding siblings ...)
  (?)
@ 2015-11-29  9:39 ` Ondrej Zary
  2015-11-30 11:50   ` Finn Thain
  -1 siblings, 1 reply; 268+ messages in thread
From: Ondrej Zary @ 2015-11-29  9:39 UTC (permalink / raw)
  To: Finn Thain, Michael Schmitz, linux-m68k, linux-scsi, linux-kernel

Convert compile-time C400_ register mapping to runtime mapping.
This removes the weird negative register offsets and allows adding
additional mappings.

Signed-off-by: Ondrej Zary <linux@rainbow-software.org>
---
 drivers/scsi/NCR5380.h   |   13 +---------
 drivers/scsi/g_NCR5380.c |   61 ++++++++++++++++++++++++++--------------------
 drivers/scsi/g_NCR5380.h |   12 ++++++---
 3 files changed, 43 insertions(+), 43 deletions(-)

diff --git a/drivers/scsi/NCR5380.h b/drivers/scsi/NCR5380.h
index 36779df..0d8ec43 100644
--- a/drivers/scsi/NCR5380.h
+++ b/drivers/scsi/NCR5380.h
@@ -163,8 +163,7 @@
 /* Write any value to this register to start an ini mode DMA receive */
 #define START_DMA_INITIATOR_RECEIVE_REG 7	/* wo */
 
-#define C400_CONTROL_STATUS_REG NCR53C400_register_offset-8	/* rw */
-
+/* C400_CONTROL_STATUS_REG */
 #define CSR_RESET              0x80	/* wo  Resets 53c400 */
 #define CSR_53C80_REG          0x80	/* ro  5380 registers busy */
 #define CSR_TRANS_DIR          0x40	/* rw  Data transfer direction */
@@ -181,16 +180,6 @@
 #define CSR_BASE CSR_53C80_INTR
 #endif
 
-/* Number of 128-byte blocks to be transferred */
-#define C400_BLOCK_COUNTER_REG   NCR53C400_register_offset-7	/* rw */
-
-/* Resume transfer after disconnect */
-#define C400_RESUME_TRANSFER_REG NCR53C400_register_offset-6	/* wo */
-
-/* Access to host buffer stack */
-#define C400_HOST_BUFFER         NCR53C400_register_offset-4	/* rw */
-
-
 /* Note : PHASE_* macros are based on the values of the STATUS register */
 #define PHASE_MASK 	(SR_MSG | SR_CD | SR_IO)
 
diff --git a/drivers/scsi/g_NCR5380.c b/drivers/scsi/g_NCR5380.c
index a9a237f..ce444da 100644
--- a/drivers/scsi/g_NCR5380.c
+++ b/drivers/scsi/g_NCR5380.c
@@ -253,6 +253,7 @@ static int __init generic_NCR5380_detect(struct scsi_host_template *tpnt)
 	};
 	int flags;
 	struct Scsi_Host *instance;
+	struct NCR5380_hostdata *hostdata;
 #ifdef SCSI_G_NCR5380_MEM
 	unsigned long base;
 	void __iomem *iomem;
@@ -395,6 +396,7 @@ static int __init generic_NCR5380_detect(struct scsi_host_template *tpnt)
 		instance = scsi_register(tpnt, sizeof(struct NCR5380_hostdata));
 		if (instance == NULL)
 			goto out_release;
+		hostdata = shost_priv(instance);
 
 #ifndef SCSI_G_NCR5380_MEM
 		instance->io_port = overrides[current_override].NCR5380_map_name;
@@ -404,18 +406,27 @@ static int __init generic_NCR5380_detect(struct scsi_host_template *tpnt)
 		 * On NCR53C400 boards, NCR5380 registers are mapped 8 past
 		 * the base address.
 		 */
-		if (overrides[current_override].board == BOARD_NCR53C400)
+		if (overrides[current_override].board == BOARD_NCR53C400) {
 			instance->io_port += 8;
+			hostdata->c400_ctl_status = 0;
+			hostdata->c400_blk_cnt = 1;
+			hostdata->c400_host_buf = 4;
+		}
 #else
 		instance->base = overrides[current_override].NCR5380_map_name;
-		((struct NCR5380_hostdata *)instance->hostdata)->iomem = iomem;
+		hostdata->iomem = iomem;
+		if (overrides[current_override].board == BOARD_NCR53C400) {
+			hostdata->c400_ctl_status = 0x100;
+			hostdata->c400_blk_cnt = 0x101;
+			hostdata->c400_host_buf = 0x104;
+		}
 #endif
 
 		if (NCR5380_init(instance, flags))
 			goto out_unregister;
 
 		if (overrides[current_override].board == BOARD_NCR53C400)
-			NCR5380_write(C400_CONTROL_STATUS_REG, CSR_BASE);
+			NCR5380_write(hostdata->c400_ctl_status, CSR_BASE);
 
 		NCR5380_maybe_reset_bus(instance);
 
@@ -523,30 +534,28 @@ generic_NCR5380_biosparam(struct scsi_device *sdev, struct block_device *bdev,
  
 static inline int NCR5380_pread(struct Scsi_Host *instance, unsigned char *dst, int len)
 {
-#ifdef SCSI_G_NCR5380_MEM
 	struct NCR5380_hostdata *hostdata = shost_priv(instance);
-#endif
 	int blocks = len / 128;
 	int start = 0;
 	int bl;
 
-	NCR5380_write(C400_CONTROL_STATUS_REG, CSR_BASE | CSR_TRANS_DIR);
-	NCR5380_write(C400_BLOCK_COUNTER_REG, blocks);
+	NCR5380_write(hostdata->c400_ctl_status, CSR_BASE | CSR_TRANS_DIR);
+	NCR5380_write(hostdata->c400_blk_cnt, blocks);
 	while (1) {
-		if ((bl = NCR5380_read(C400_BLOCK_COUNTER_REG)) == 0) {
+		if ((bl = NCR5380_read(hostdata->c400_blk_cnt)) == 0) {
 			break;
 		}
-		if (NCR5380_read(C400_CONTROL_STATUS_REG) & CSR_GATED_53C80_IRQ) {
+		if (NCR5380_read(hostdata->c400_ctl_status) & CSR_GATED_53C80_IRQ) {
 			printk(KERN_ERR "53C400r: Got 53C80_IRQ start=%d, blocks=%d\n", start, blocks);
 			return -1;
 		}
-		while (NCR5380_read(C400_CONTROL_STATUS_REG) & CSR_HOST_BUF_NOT_RDY);
+		while (NCR5380_read(hostdata->c400_ctl_status) & CSR_HOST_BUF_NOT_RDY);
 
 #ifndef SCSI_G_NCR5380_MEM
 		{
 			int i;
 			for (i = 0; i < 128; i++)
-				dst[start + i] = NCR5380_read(C400_HOST_BUFFER);
+				dst[start + i] = NCR5380_read(hostdata->c400_host_buf);
 		}
 #else
 		/* implies SCSI_G_NCR5380_MEM */
@@ -558,7 +567,7 @@ static inline int NCR5380_pread(struct Scsi_Host *instance, unsigned char *dst,
 	}
 
 	if (blocks) {
-		while (NCR5380_read(C400_CONTROL_STATUS_REG) & CSR_HOST_BUF_NOT_RDY)
+		while (NCR5380_read(hostdata->c400_ctl_status) & CSR_HOST_BUF_NOT_RDY)
 		{
 			// FIXME - no timeout
 		}
@@ -567,7 +576,7 @@ static inline int NCR5380_pread(struct Scsi_Host *instance, unsigned char *dst,
 		{
 			int i;	
 			for (i = 0; i < 128; i++)
-				dst[start + i] = NCR5380_read(C400_HOST_BUFFER);
+				dst[start + i] = NCR5380_read(hostdata->c400_host_buf);
 		}
 #else
 		/* implies SCSI_G_NCR5380_MEM */
@@ -578,7 +587,7 @@ static inline int NCR5380_pread(struct Scsi_Host *instance, unsigned char *dst,
 		blocks--;
 	}
 
-	if (!(NCR5380_read(C400_CONTROL_STATUS_REG) & CSR_GATED_53C80_IRQ))
+	if (!(NCR5380_read(hostdata->c400_ctl_status) & CSR_GATED_53C80_IRQ))
 		printk("53C400r: no 53C80 gated irq after transfer");
 
 #if 0
@@ -586,7 +595,7 @@ static inline int NCR5380_pread(struct Scsi_Host *instance, unsigned char *dst,
 	 *	DON'T DO THIS - THEY NEVER ARRIVE!
 	 */
 	printk("53C400r: Waiting for 53C80 registers\n");
-	while (NCR5380_read(C400_CONTROL_STATUS_REG) & CSR_53C80_REG)
+	while (NCR5380_read(hostdata->c400_ctl_status) & CSR_53C80_REG)
 		;
 #endif
 	if (!(NCR5380_read(BUS_AND_STATUS_REG) & BASR_END_DMA_TRANSFER))
@@ -607,31 +616,29 @@ static inline int NCR5380_pread(struct Scsi_Host *instance, unsigned char *dst,
 
 static inline int NCR5380_pwrite(struct Scsi_Host *instance, unsigned char *src, int len)
 {
-#ifdef SCSI_G_NCR5380_MEM
 	struct NCR5380_hostdata *hostdata = shost_priv(instance);
-#endif
 	int blocks = len / 128;
 	int start = 0;
 	int bl;
 	int i;
 
-	NCR5380_write(C400_CONTROL_STATUS_REG, CSR_BASE);
-	NCR5380_write(C400_BLOCK_COUNTER_REG, blocks);
+	NCR5380_write(hostdata->c400_ctl_status, CSR_BASE);
+	NCR5380_write(hostdata->c400_blk_cnt, blocks);
 	while (1) {
-		if (NCR5380_read(C400_CONTROL_STATUS_REG) & CSR_GATED_53C80_IRQ) {
+		if (NCR5380_read(hostdata->c400_ctl_status) & CSR_GATED_53C80_IRQ) {
 			printk(KERN_ERR "53C400w: Got 53C80_IRQ start=%d, blocks=%d\n", start, blocks);
 			return -1;
 		}
 
-		if ((bl = NCR5380_read(C400_BLOCK_COUNTER_REG)) == 0) {
+		if ((bl = NCR5380_read(hostdata->c400_blk_cnt)) == 0) {
 			break;
 		}
-		while (NCR5380_read(C400_CONTROL_STATUS_REG) & CSR_HOST_BUF_NOT_RDY)
+		while (NCR5380_read(hostdata->c400_ctl_status) & CSR_HOST_BUF_NOT_RDY)
 			; // FIXME - timeout
 #ifndef SCSI_G_NCR5380_MEM
 		{
 			for (i = 0; i < 128; i++)
-				NCR5380_write(C400_HOST_BUFFER, src[start + i]);
+				NCR5380_write(hostdata->c400_host_buf, src[start + i]);
 		}
 #else
 		/* implies SCSI_G_NCR5380_MEM */
@@ -642,13 +649,13 @@ static inline int NCR5380_pwrite(struct Scsi_Host *instance, unsigned char *src,
 		blocks--;
 	}
 	if (blocks) {
-		while (NCR5380_read(C400_CONTROL_STATUS_REG) & CSR_HOST_BUF_NOT_RDY)
+		while (NCR5380_read(hostdata->c400_ctl_status) & CSR_HOST_BUF_NOT_RDY)
 			; // FIXME - no timeout
 
 #ifndef SCSI_G_NCR5380_MEM
 		{
 			for (i = 0; i < 128; i++)
-				NCR5380_write(C400_HOST_BUFFER, src[start + i]);
+				NCR5380_write(hostdata->c400_host_buf, src[start + i]);
 		}
 #else
 		/* implies SCSI_G_NCR5380_MEM */
@@ -661,7 +668,7 @@ static inline int NCR5380_pwrite(struct Scsi_Host *instance, unsigned char *src,
 
 #if 0
 	printk("53C400w: waiting for registers to be available\n");
-	THEY NEVER DO ! while (NCR5380_read(C400_CONTROL_STATUS_REG) & CSR_53C80_REG);
+	THEY NEVER DO ! while (NCR5380_read(hostdata->c400_ctl_status) & CSR_53C80_REG);
 	printk("53C400w: Got em\n");
 #endif
 
@@ -669,7 +676,7 @@ static inline int NCR5380_pwrite(struct Scsi_Host *instance, unsigned char *src,
 	/* All documentation says to check for this. Maybe my hardware is too
 	 * fast. Waiting for it seems to work fine! KLL
 	 */
-	while (!(i = NCR5380_read(C400_CONTROL_STATUS_REG) & CSR_GATED_53C80_IRQ))
+	while (!(i = NCR5380_read(hostdata->c400_ctl_status) & CSR_GATED_53C80_IRQ))
 		;	// FIXME - no timeout
 
 	/*
diff --git a/drivers/scsi/g_NCR5380.h b/drivers/scsi/g_NCR5380.h
index fd201e9..633edd0 100644
--- a/drivers/scsi/g_NCR5380.h
+++ b/drivers/scsi/g_NCR5380.h
@@ -29,7 +29,6 @@
 
 #define NCR5380_map_type int
 #define NCR5380_map_name port
-#define NCR53C400_register_offset 0
 
 #ifdef CONFIG_SCSI_GENERIC_NCR53C400
 #define NCR5380_region_size 16
@@ -42,7 +41,10 @@
 #define NCR5380_write(reg, value) \
 	outb(value, instance->io_port + (reg))
 
-#define NCR5380_implementation_fields /* none */
+#define NCR5380_implementation_fields \
+	int c400_ctl_status;\
+	int c400_blk_cnt;\
+	int c400_host_buf;
 
 #else 
 /* therefore SCSI_G_NCR5380_MEM */
@@ -50,7 +52,6 @@
 
 #define NCR5380_map_type unsigned long
 #define NCR5380_map_name base
-#define NCR53C400_register_offset 0x108
 #define NCR53C400_mem_base 0x3880
 #define NCR53C400_host_buffer 0x3900
 #define NCR5380_region_size 0x3a00
@@ -63,7 +64,10 @@
 	       NCR53C400_mem_base + (reg))
 
 #define NCR5380_implementation_fields \
-    void __iomem *iomem;
+	void __iomem *iomem;\
+	int c400_ctl_status;\
+	int c400_blk_cnt;\
+	int c400_host_buf;
 
 #endif
 
-- 
Ondrej Zary


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

* [RFC PATCH 74/71] ncr5380: Enable PDMA for NCR53C400A
  2015-11-18  8:34 ` Finn Thain
                   ` (74 preceding siblings ...)
  (?)
@ 2015-11-29  9:39 ` Ondrej Zary
  2015-11-30 11:52   ` Finn Thain
  2015-11-30 12:04   ` Finn Thain
  -1 siblings, 2 replies; 268+ messages in thread
From: Ondrej Zary @ 2015-11-29  9:39 UTC (permalink / raw)
  To: Finn Thain, Michael Schmitz, linux-m68k, linux-scsi, linux-kernel

Add I/O register mapping for NCR53C400A and enable PDMA mode to
improve performance and fix non-working IRQ.

Tested with HP C2502 (and user-space enabler).

Signed-off-by: Ondrej Zary <linux@rainbow-software.org>
---
 drivers/scsi/g_NCR5380.c |   11 ++++++++++-
 1 file changed, 10 insertions(+), 1 deletion(-)

diff --git a/drivers/scsi/g_NCR5380.c b/drivers/scsi/g_NCR5380.c
index ce444da..c3abe48 100644
--- a/drivers/scsi/g_NCR5380.c
+++ b/drivers/scsi/g_NCR5380.c
@@ -324,7 +324,10 @@ static int __init generic_NCR5380_detect(struct scsi_host_template *tpnt)
 #endif
 			break;
 		case BOARD_NCR53C400A:
+			flags = FLAG_NO_DMA_FIXUP;
+#ifndef PSEUDO_DMA
 			flags = FLAG_NO_PSEUDO_DMA;
+#endif
 			ports = ncr_53c400a_ports;
 			break;
 		case BOARD_DTC3181E:
@@ -412,6 +415,11 @@ static int __init generic_NCR5380_detect(struct scsi_host_template *tpnt)
 			hostdata->c400_blk_cnt = 1;
 			hostdata->c400_host_buf = 4;
 		}
+		if (overrides[current_override].board == BOARD_NCR53C400A) {
+			hostdata->c400_ctl_status = 9;
+			hostdata->c400_blk_cnt = 10;
+			hostdata->c400_host_buf = 8;
+		}
 #else
 		instance->base = overrides[current_override].NCR5380_map_name;
 		hostdata->iomem = iomem;
@@ -425,7 +433,8 @@ static int __init generic_NCR5380_detect(struct scsi_host_template *tpnt)
 		if (NCR5380_init(instance, flags))
 			goto out_unregister;
 
-		if (overrides[current_override].board == BOARD_NCR53C400)
+		if (overrides[current_override].board == BOARD_NCR53C400 ||
+		    overrides[current_override].board == BOARD_NCR53C400A)
 			NCR5380_write(hostdata->c400_ctl_status, CSR_BASE);
 
 		NCR5380_maybe_reset_bus(instance);
-- 
Ondrej Zary


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

* [RFC PATCH 75/71] ncr5380: Remove FLAG_DTC3181E
  2015-11-18  8:34 ` Finn Thain
                   ` (75 preceding siblings ...)
  (?)
@ 2015-11-29 10:01 ` Ondrej Zary
  2015-11-30  4:56   ` Finn Thain
  -1 siblings, 1 reply; 268+ messages in thread
From: Ondrej Zary @ 2015-11-29 10:01 UTC (permalink / raw)
  To: Finn Thain, Michael Schmitz, linux-m68k, linux-scsi, linux-kernel

The FLAG_DTC3181E is used to activate a work-around for arbitration lost
condition that these chips see when ICR is written during arbitration.

Move the ICR write (to set SEL and BSY) after the arbitration loss check
and remove FLAG_DTC3181E.

Signed-off-by: Ondrej Zary <linux@rainbow-software.org>
---
Weird, we now have two consecutive checks for ICR_ARBITRATION_LOST and
do different things when they fail...

 drivers/scsi/NCR5380.c       |   23 +++++++++--------------
 drivers/scsi/NCR5380.h       |    1 -
 drivers/scsi/atari_NCR5380.c |   23 +++++++++--------------
 drivers/scsi/dmx3191d.c      |    2 +-
 drivers/scsi/g_NCR5380.c     |    2 +-
 5 files changed, 20 insertions(+), 31 deletions(-)

diff --git a/drivers/scsi/NCR5380.c b/drivers/scsi/NCR5380.c
index acb359a..b617f99 100644
--- a/drivers/scsi/NCR5380.c
+++ b/drivers/scsi/NCR5380.c
@@ -482,14 +482,13 @@ static void prepare_info(struct Scsi_Host *instance)
 	         "base 0x%lx, irq %d, "
 	         "can_queue %d, cmd_per_lun %d, "
 	         "sg_tablesize %d, this_id %d, "
-	         "flags { %s%s%s%s}, "
+	         "flags { %s%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_NO_DMA_FIXUP  ? "NO_DMA_FIXUP "  : "",
-	         hostdata->flags & FLAG_DTC3181E      ? "DTC3181E "      : "",
 	         hostdata->flags & FLAG_NO_PSEUDO_DMA ? "NO_PSEUDO_DMA " : "",
 	         hostdata->flags & FLAG_TOSHIBA_DELAY ? "TOSHIBA_DELAY "  : "",
 #ifdef AUTOPROBE_IRQ
@@ -1078,18 +1077,7 @@ static struct scsi_cmnd *NCR5380_select(struct Scsi_Host *instance,
 		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);
-
-	/* RvC: DTC3181E has some trouble with this so we simply removed it.
-	 * Seems to work with only Mustek scanner attached.
-	 */
-	if (!(hostdata->flags & FLAG_DTC3181E) &&
-	    (NCR5380_read(INITIATOR_COMMAND_REG) & ICR_ARBITRATION_LOST)) {
+	if (NCR5380_read(INITIATOR_COMMAND_REG) & ICR_ARBITRATION_LOST) {
 		NCR5380_write(MODE_REG, MR_BASE);
 		NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
 		dsprintk(NDEBUG_ARBITRATION, instance, "arbitration lost, negating SEL\n");
@@ -1097,6 +1085,13 @@ static struct scsi_cmnd *NCR5380_select(struct Scsi_Host *instance,
 		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)
diff --git a/drivers/scsi/NCR5380.h b/drivers/scsi/NCR5380.h
index 0d8ec43..5092580 100644
--- a/drivers/scsi/NCR5380.h
+++ b/drivers/scsi/NCR5380.h
@@ -222,7 +222,6 @@
 
 #define FLAG_NO_DMA_FIXUP		1	/* No DMA errata workarounds */
 #define FLAG_NO_PSEUDO_DMA		8	/* Inhibit DMA */
-#define FLAG_DTC3181E			16	/* DTC3181E */
 #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 */
diff --git a/drivers/scsi/atari_NCR5380.c b/drivers/scsi/atari_NCR5380.c
index d04374d..7640110 100644
--- a/drivers/scsi/atari_NCR5380.c
+++ b/drivers/scsi/atari_NCR5380.c
@@ -586,13 +586,12 @@ static void prepare_info(struct Scsi_Host *instance)
 	         "base 0x%lx, irq %d, "
 	         "can_queue %d, cmd_per_lun %d, "
 	         "sg_tablesize %d, this_id %d, "
-	         "flags { %s%s%s}, "
+	         "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_DTC3181E       ? "DTC3181E "       : "",
 	         hostdata->flags & FLAG_TAGGED_QUEUING ? "TAGGED_QUEUING " : "",
 	         hostdata->flags & FLAG_TOSHIBA_DELAY  ? "TOSHIBA_DELAY "  : "",
 #ifdef DIFFERENTIAL
@@ -1279,18 +1278,7 @@ static struct scsi_cmnd *NCR5380_select(struct Scsi_Host *instance,
 		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);
-
-	/* RvC: DTC3181E has some trouble with this so we simply removed it.
-	 * Seems to work with only Mustek scanner attached.
-	 */
-	if (!(hostdata->flags & FLAG_DTC3181E) &&
-	    (NCR5380_read(INITIATOR_COMMAND_REG) & ICR_ARBITRATION_LOST)) {
+	if (NCR5380_read(INITIATOR_COMMAND_REG) & ICR_ARBITRATION_LOST) {
 		NCR5380_write(MODE_REG, MR_BASE);
 		NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
 		dsprintk(NDEBUG_ARBITRATION, instance, "arbitration lost, negating SEL\n");
@@ -1298,6 +1286,13 @@ static struct scsi_cmnd *NCR5380_select(struct Scsi_Host *instance,
 		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)
diff --git a/drivers/scsi/dmx3191d.c b/drivers/scsi/dmx3191d.c
index 3c60dfb..ddb4e61 100644
--- a/drivers/scsi/dmx3191d.c
+++ b/drivers/scsi/dmx3191d.c
@@ -92,7 +92,7 @@ static int dmx3191d_probe_one(struct pci_dev *pdev,
 	 */
 	shost->irq = NO_IRQ;
 
-	error = NCR5380_init(shost, FLAG_NO_PSEUDO_DMA | FLAG_DTC3181E);
+	error = NCR5380_init(shost, FLAG_NO_PSEUDO_DMA);
 	if (error)
 		goto out_host_put;
 
diff --git a/drivers/scsi/g_NCR5380.c b/drivers/scsi/g_NCR5380.c
index c3abe48..fae4332 100644
--- a/drivers/scsi/g_NCR5380.c
+++ b/drivers/scsi/g_NCR5380.c
@@ -331,7 +331,7 @@ static int __init generic_NCR5380_detect(struct scsi_host_template *tpnt)
 			ports = ncr_53c400a_ports;
 			break;
 		case BOARD_DTC3181E:
-			flags = FLAG_NO_PSEUDO_DMA | FLAG_DTC3181E;
+			flags = FLAG_NO_PSEUDO_DMA;
 			ports = dtc_3181e_ports;
 			break;
 		}
-- 
Ondrej Zary


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

* Re: [PATCH 22/71] ncr5380: Eliminate selecting state
  2015-11-29  9:27               ` Geert Uytterhoeven
@ 2015-11-29 10:25                 ` Finn Thain
  2015-11-29 13:50                   ` Geert Uytterhoeven
  0 siblings, 1 reply; 268+ messages in thread
From: Finn Thain @ 2015-11-29 10:25 UTC (permalink / raw)
  To: Geert Uytterhoeven
  Cc: Ondrej Zary, James E.J. Bottomley, Michael Schmitz, Linux/m68k,
	scsi, linux-kernel


On Sun, 29 Nov 2015, Geert Uytterhoeven wrote:

> This still heavily depends on the processing time spent in 
> NCR5380_read(). You should never use a value derived from 
> loops_per_jiffy for a non-empty loop,

Sure but the time-out condition isn't supposed to be precise.
Plus/minus a jiffy is no problem. Plus/minus a second is no good.

> as it may take much longer. Always compare with an maximum end time 
> instead.

That can't work with interrupts disabled, which was the problem I was 
trying to solve by use of loops_per_jiffy.

NCR5380_poll_politely() in mainline doesn't work with interrupts disabled 
either, hence patch 21.

> 
> E.g.:
> 
>         end = jiffies + 2;        /* 1 jiffie + 1 safeguard */
>         do {
>                  if ((NCR5380_read(reg1) & bit1) == val1)
>                          return 0;
>                  cpu_relax();
>         } while (time_before(jiffies, end);
> 
> And a similar loop for "Busy-wait for up to 20 ms".

Interrupts may be disabled during that loop also. Please refer to (and/or 
respond to) patch 21, "ncr5380: Sleep when polling, if possible", in which 
these changes were made.

-- 

> 
> Gr{oetje,eeting}s,
> 
>                         Geert
> 

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

* Re: [PATCH 22/71] ncr5380: Eliminate selecting state
  2015-11-29 10:25                 ` Finn Thain
@ 2015-11-29 13:50                   ` Geert Uytterhoeven
  2015-11-30  2:12                     ` Finn Thain
  0 siblings, 1 reply; 268+ messages in thread
From: Geert Uytterhoeven @ 2015-11-29 13:50 UTC (permalink / raw)
  To: Finn Thain
  Cc: Ondrej Zary, James E.J. Bottomley, Michael Schmitz, Linux/m68k,
	scsi, linux-kernel

Hi Finn,

On Sun, Nov 29, 2015 at 11:25 AM, Finn Thain <fthain@telegraphics.com.au> wrote:
> On Sun, 29 Nov 2015, Geert Uytterhoeven wrote:
>> This still heavily depends on the processing time spent in
>> NCR5380_read(). You should never use a value derived from
>> loops_per_jiffy for a non-empty loop,
>
> Sure but the time-out condition isn't supposed to be precise.
> Plus/minus a jiffy is no problem. Plus/minus a second is no good.

If an ISA access takes 8 µs, while the CPU runs at 1 GHz, i.e. 500M loops/s,
the difference will be huge.

>> as it may take much longer. Always compare with an maximum end time
>> instead.
>
> That can't work with interrupts disabled, which was the problem I was
> trying to solve by use of loops_per_jiffy.

Then you indeed can't use jiffies.
Perhaps you can calibrate an NCR5380_read() loop at driver init time,
and use the calibration value later?

> NCR5380_poll_politely() in mainline doesn't work with interrupts disabled
> either, hence patch 21.
>
>> E.g.:
>>
>>         end = jiffies + 2;        /* 1 jiffie + 1 safeguard */
>>         do {
>>                  if ((NCR5380_read(reg1) & bit1) == val1)
>>                          return 0;
>>                  cpu_relax();
>>         } while (time_before(jiffies, end);
>>
>> And a similar loop for "Busy-wait for up to 20 ms".
>
> Interrupts may be disabled during that loop also. Please refer to (and/or
> respond to) patch 21, "ncr5380: Sleep when polling, if possible", in which
> these changes were made.

So the above loop may never terminate. Oops...

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] 268+ messages in thread

* Re: [PATCH 22/71] ncr5380: Eliminate selecting state
  2015-11-29 13:50                   ` Geert Uytterhoeven
@ 2015-11-30  2:12                     ` Finn Thain
  0 siblings, 0 replies; 268+ messages in thread
From: Finn Thain @ 2015-11-30  2:12 UTC (permalink / raw)
  To: Geert Uytterhoeven
  Cc: Ondrej Zary, James E.J. Bottomley, Michael Schmitz, linux-m68k,
	linux-scsi, linux-kernel


On Sun, 29 Nov 2015, Geert Uytterhoeven wrote:

> If an ISA access takes 8 us, while the CPU runs at 1 GHz, i.e. 500M 
> loops/s, the difference will be huge.

Ondrej showed that an ISA access can take about 1.6 us. I don't know what 
to make of the "8 uS" comment in the mainline driver. Maybe it was an even 
slower ISA card.

Anyway, I made a measurement on my hardware and confirmed that lpj is a 
very bad proxy for device register access throughput. The "loops per 
access" gap is several orders of magnitude:

                                      lpj   HZ    access time (us)  lpa
------------------------------------------------------------------------
Ondrej's 5380 ISA card (PC):      4797252   250   1.6               1.9k
My DMX3191D PCI card (PowerMac):   167079   100   0.42              7.0

> 
> Perhaps you can calibrate an NCR5380_read() loop at driver init time, 
> and use the calibration value later?

I had the same idea but I didn't think that the complexity was justified 
by the low precision requirement. But now that I have some timings I have 
to agree.

-- 

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

* Re: [RFC PATCH 75/71] ncr5380: Remove FLAG_DTC3181E
  2015-11-29 10:01 ` [RFC PATCH 75/71] ncr5380: Remove FLAG_DTC3181E Ondrej Zary
@ 2015-11-30  4:56   ` Finn Thain
  0 siblings, 0 replies; 268+ messages in thread
From: Finn Thain @ 2015-11-30  4:56 UTC (permalink / raw)
  To: Ondrej Zary; +Cc: Michael Schmitz, linux-m68k, linux-scsi, linux-kernel


On Sun, 29 Nov 2015, Ondrej Zary wrote:

> The FLAG_DTC3181E is used to activate a work-around for arbitration lost
> condition that these chips see when ICR is written during arbitration.
> 
> Move the ICR write (to set SEL and BSY) after the arbitration loss check
> and remove FLAG_DTC3181E.

The first test for ICR_ARBITRATION_LOST happens after the required 
arbitration delay, 2.4 us. The second test for ICR_ARBITRATION_LOST 
happens after ICR_ASSERT_SEL.

This second test seems to be pointless. It comes from the flow chart in 
the NCR datasheet (see download link in patch 17). The spec does not 
require this test but some 5380 devices may do. Who knows? It's almost 
impossible to be sure, because it would mean losing a race with another 
bus device right at the end of the arbitration delay (and we extend that 
delay to 3 us anyway).

Certainly one can find other datasheets with sample code and flow charts 
that don't do this second check. The reason is that ICR_ARBITRATION_LOST 
can be triggered when SEL is asserted by any device, so it may be 
triggered after we've won arbitration (because we then set ICR_ASSERT_SEL 
ourselves in order to enter selection phase).

> 
> ... Weird, we now have two consecutive checks for ICR_ARBITRATION_LOST 
> and do different things when they fail...

They do different things because the second exit has to cleanup after the 
ICR write.

I agree that it would be nice to remove the DTC3181E special case. It 
would mean replacing patch 49.

The patch below is another version of your patch 75. It really needs to be 
tested on all kinds of 5380 device, and if possible with a contested bus 
(which would imply diconnection privileges, for which the driver still 
requires that the chip has a working irq).

Index: linux/drivers/scsi/NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/NCR5380.c	2015-11-30 15:34:39.000000000 +1100
+++ linux/drivers/scsi/NCR5380.c	2015-11-30 15:34:39.000000000 +1100
@@ -482,14 +482,13 @@ static void prepare_info(struct Scsi_Hos
 	         "base 0x%lx, irq %d, "
 	         "can_queue %d, cmd_per_lun %d, "
 	         "sg_tablesize %d, this_id %d, "
-	         "flags { %s%s%s%s}, "
+	         "flags { %s%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_NO_DMA_FIXUP  ? "NO_DMA_FIXUP "  : "",
-	         hostdata->flags & FLAG_DTC3181E      ? "DTC3181E "      : "",
 	         hostdata->flags & FLAG_NO_PSEUDO_DMA ? "NO_PSEUDO_DMA " : "",
 	         hostdata->flags & FLAG_TOSHIBA_DELAY ? "TOSHIBA_DELAY "  : "",
 #ifdef AUTOPROBE_IRQ
@@ -1085,18 +1084,6 @@ static struct scsi_cmnd *NCR5380_select(
 	NCR5380_write(INITIATOR_COMMAND_REG,
 		      ICR_BASE | ICR_ASSERT_SEL | ICR_ASSERT_BSY);
 
-	/* RvC: DTC3181E has some trouble with this so we simply removed it.
-	 * Seems to work with only Mustek scanner attached.
-	 */
-	if (!(hostdata->flags & FLAG_DTC3181E) &&
-	    (NCR5380_read(INITIATOR_COMMAND_REG) & ICR_ARBITRATION_LOST)) {
-		NCR5380_write(MODE_REG, MR_BASE);
-		NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
-		dsprintk(NDEBUG_ARBITRATION, instance, "arbitration lost, negating SEL\n");
-		spin_lock_irq(&hostdata->lock);
-		goto out;
-	}
-
 	/*
 	 * Again, bus clear + bus settle time is 1.2us, however, this is
 	 * a minimum so we'll udelay ceil(1.2)
Index: linux/drivers/scsi/NCR5380.h
===================================================================
--- linux.orig/drivers/scsi/NCR5380.h	2015-11-30 15:34:36.000000000 +1100
+++ linux/drivers/scsi/NCR5380.h	2015-11-30 15:34:39.000000000 +1100
@@ -233,7 +233,6 @@
 
 #define FLAG_NO_DMA_FIXUP		1	/* No DMA errata workarounds */
 #define FLAG_NO_PSEUDO_DMA		8	/* Inhibit DMA */
-#define FLAG_DTC3181E			16	/* DTC3181E */
 #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 */
Index: linux/drivers/scsi/atari_NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/atari_NCR5380.c	2015-11-30 15:34:39.000000000 +1100
+++ linux/drivers/scsi/atari_NCR5380.c	2015-11-30 15:34:39.000000000 +1100
@@ -586,13 +586,12 @@ static void prepare_info(struct Scsi_Hos
 	         "base 0x%lx, irq %d, "
 	         "can_queue %d, cmd_per_lun %d, "
 	         "sg_tablesize %d, this_id %d, "
-	         "flags { %s%s%s}, "
+	         "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_DTC3181E       ? "DTC3181E "       : "",
 	         hostdata->flags & FLAG_TAGGED_QUEUING ? "TAGGED_QUEUING " : "",
 	         hostdata->flags & FLAG_TOSHIBA_DELAY  ? "TOSHIBA_DELAY "  : "",
 #ifdef DIFFERENTIAL
@@ -1286,18 +1285,6 @@ static struct scsi_cmnd *NCR5380_select(
 	NCR5380_write(INITIATOR_COMMAND_REG,
 		      ICR_BASE | ICR_ASSERT_SEL | ICR_ASSERT_BSY);
 
-	/* RvC: DTC3181E has some trouble with this so we simply removed it.
-	 * Seems to work with only Mustek scanner attached.
-	 */
-	if (!(hostdata->flags & FLAG_DTC3181E) &&
-	    (NCR5380_read(INITIATOR_COMMAND_REG) & ICR_ARBITRATION_LOST)) {
-		NCR5380_write(MODE_REG, MR_BASE);
-		NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
-		dsprintk(NDEBUG_ARBITRATION, instance, "arbitration lost, negating SEL\n");
-		spin_lock_irq(&hostdata->lock);
-		goto out;
-	}
-
 	/*
 	 * Again, bus clear + bus settle time is 1.2us, however, this is
 	 * a minimum so we'll udelay ceil(1.2)
Index: linux/drivers/scsi/g_NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/g_NCR5380.c	2015-11-30 15:34:39.000000000 +1100
+++ linux/drivers/scsi/g_NCR5380.c	2015-11-30 15:34:39.000000000 +1100
@@ -326,7 +326,7 @@ static int __init generic_NCR5380_detect
 			ports = ncr_53c400a_ports;
 			break;
 		case BOARD_DTC3181E:
-			flags = FLAG_NO_PSEUDO_DMA | FLAG_DTC3181E;
+			flags = FLAG_NO_PSEUDO_DMA;
 			ports = dtc_3181e_ports;
 			break;
 		}
Index: linux/drivers/scsi/dmx3191d.c
===================================================================
--- linux.orig/drivers/scsi/dmx3191d.c	2015-11-30 15:34:35.000000000 +1100
+++ linux/drivers/scsi/dmx3191d.c	2015-11-30 15:34:39.000000000 +1100
@@ -92,7 +92,7 @@ static int dmx3191d_probe_one(struct pci
 	 */
 	shost->irq = NO_IRQ;
 
-	error = NCR5380_init(shost, FLAG_NO_PSEUDO_DMA | FLAG_DTC3181E);
+	error = NCR5380_init(shost, FLAG_NO_PSEUDO_DMA);
 	if (error)
 		goto out_host_put;
 

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

* Re: [RFC PATCH 73/71] ncr5380: Use runtime register mapping
  2015-11-29  9:39 ` [RFC PATCH 73/71] ncr5380: Use runtime register mapping Ondrej Zary
@ 2015-11-30 11:50   ` Finn Thain
  0 siblings, 0 replies; 268+ messages in thread
From: Finn Thain @ 2015-11-30 11:50 UTC (permalink / raw)
  To: Ondrej Zary; +Cc: Michael Schmitz, linux-m68k, linux-scsi, linux-kernel


On Sun, 29 Nov 2015, Ondrej Zary wrote:

> Convert compile-time C400_ register mapping to runtime mapping.
> This removes the weird negative register offsets and allows adding
> additional mappings.
> 
> Signed-off-by: Ondrej Zary <linux@rainbow-software.org>
> ---
>  drivers/scsi/NCR5380.h   |   13 +---------
>  drivers/scsi/g_NCR5380.c |   61 ++++++++++++++++++++++++++--------------------
>  drivers/scsi/g_NCR5380.h |   12 ++++++---
>  3 files changed, 43 insertions(+), 43 deletions(-)
> 
> diff --git a/drivers/scsi/NCR5380.h b/drivers/scsi/NCR5380.h
> index 36779df..0d8ec43 100644
> --- a/drivers/scsi/NCR5380.h
> +++ b/drivers/scsi/NCR5380.h
> @@ -163,8 +163,7 @@
>  /* Write any value to this register to start an ini mode DMA receive */
>  #define START_DMA_INITIATOR_RECEIVE_REG 7	/* wo */
>  
> -#define C400_CONTROL_STATUS_REG NCR53C400_register_offset-8	/* rw */
> -
> +/* C400_CONTROL_STATUS_REG */

That symbol is removed by this patch. No need for abbreviations. How about

/* NCR 53C400 and 53C400A Control Status Register bits: */

>  #define CSR_RESET              0x80	/* wo  Resets 53c400 */
>  #define CSR_53C80_REG          0x80	/* ro  5380 registers busy */
>  #define CSR_TRANS_DIR          0x40	/* rw  Data transfer direction */
> @@ -181,16 +180,6 @@
>  #define CSR_BASE CSR_53C80_INTR
>  #endif
>  
> -/* Number of 128-byte blocks to be transferred */
> -#define C400_BLOCK_COUNTER_REG   NCR53C400_register_offset-7	/* rw */
> -
> -/* Resume transfer after disconnect */
> -#define C400_RESUME_TRANSFER_REG NCR53C400_register_offset-6	/* wo */
> -
> -/* Access to host buffer stack */
> -#define C400_HOST_BUFFER         NCR53C400_register_offset-4	/* rw */
> -
> -
>  /* Note : PHASE_* macros are based on the values of the STATUS register */
>  #define PHASE_MASK 	(SR_MSG | SR_CD | SR_IO)
>  
> diff --git a/drivers/scsi/g_NCR5380.c b/drivers/scsi/g_NCR5380.c
> index a9a237f..ce444da 100644
> --- a/drivers/scsi/g_NCR5380.c
> +++ b/drivers/scsi/g_NCR5380.c
> @@ -253,6 +253,7 @@ static int __init generic_NCR5380_detect(struct scsi_host_template *tpnt)
>  	};
>  	int flags;
>  	struct Scsi_Host *instance;
> +	struct NCR5380_hostdata *hostdata;
>  #ifdef SCSI_G_NCR5380_MEM
>  	unsigned long base;
>  	void __iomem *iomem;
> @@ -395,6 +396,7 @@ static int __init generic_NCR5380_detect(struct scsi_host_template *tpnt)
>  		instance = scsi_register(tpnt, sizeof(struct NCR5380_hostdata));
>  		if (instance == NULL)
>  			goto out_release;
> +		hostdata = shost_priv(instance);
>  
>  #ifndef SCSI_G_NCR5380_MEM
>  		instance->io_port = overrides[current_override].NCR5380_map_name;
> @@ -404,18 +406,27 @@ static int __init generic_NCR5380_detect(struct scsi_host_template *tpnt)
>  		 * On NCR53C400 boards, NCR5380 registers are mapped 8 past
>  		 * the base address.
>  		 */
> -		if (overrides[current_override].board == BOARD_NCR53C400)
> +		if (overrides[current_override].board == BOARD_NCR53C400) {
>  			instance->io_port += 8;
> +			hostdata->c400_ctl_status = 0;
> +			hostdata->c400_blk_cnt = 1;
> +			hostdata->c400_host_buf = 4;
> +		}
>  #else
>  		instance->base = overrides[current_override].NCR5380_map_name;
> -		((struct NCR5380_hostdata *)instance->hostdata)->iomem = iomem;
> +		hostdata->iomem = iomem;
> +		if (overrides[current_override].board == BOARD_NCR53C400) {
> +			hostdata->c400_ctl_status = 0x100;
> +			hostdata->c400_blk_cnt = 0x101;
> +			hostdata->c400_host_buf = 0x104;
> +		}
>  #endif
>  
>  		if (NCR5380_init(instance, flags))
>  			goto out_unregister;
>  
>  		if (overrides[current_override].board == BOARD_NCR53C400)
> -			NCR5380_write(C400_CONTROL_STATUS_REG, CSR_BASE);
> +			NCR5380_write(hostdata->c400_ctl_status, CSR_BASE);
>  
>  		NCR5380_maybe_reset_bus(instance);
>  
> @@ -523,30 +534,28 @@ generic_NCR5380_biosparam(struct scsi_device *sdev, struct block_device *bdev,
>   
>  static inline int NCR5380_pread(struct Scsi_Host *instance, unsigned char *dst, int len)
>  {
> -#ifdef SCSI_G_NCR5380_MEM
>  	struct NCR5380_hostdata *hostdata = shost_priv(instance);
> -#endif
>  	int blocks = len / 128;
>  	int start = 0;
>  	int bl;
>  
> -	NCR5380_write(C400_CONTROL_STATUS_REG, CSR_BASE | CSR_TRANS_DIR);
> -	NCR5380_write(C400_BLOCK_COUNTER_REG, blocks);
> +	NCR5380_write(hostdata->c400_ctl_status, CSR_BASE | CSR_TRANS_DIR);
> +	NCR5380_write(hostdata->c400_blk_cnt, blocks);
>  	while (1) {
> -		if ((bl = NCR5380_read(C400_BLOCK_COUNTER_REG)) == 0) {
> +		if ((bl = NCR5380_read(hostdata->c400_blk_cnt)) == 0) {
>  			break;
>  		}
> -		if (NCR5380_read(C400_CONTROL_STATUS_REG) & CSR_GATED_53C80_IRQ) {
> +		if (NCR5380_read(hostdata->c400_ctl_status) & CSR_GATED_53C80_IRQ) {
>  			printk(KERN_ERR "53C400r: Got 53C80_IRQ start=%d, blocks=%d\n", start, blocks);
>  			return -1;
>  		}
> -		while (NCR5380_read(C400_CONTROL_STATUS_REG) & CSR_HOST_BUF_NOT_RDY);
> +		while (NCR5380_read(hostdata->c400_ctl_status) & CSR_HOST_BUF_NOT_RDY);
>  
>  #ifndef SCSI_G_NCR5380_MEM
>  		{
>  			int i;
>  			for (i = 0; i < 128; i++)
> -				dst[start + i] = NCR5380_read(C400_HOST_BUFFER);
> +				dst[start + i] = NCR5380_read(hostdata->c400_host_buf);
>  		}
>  #else
>  		/* implies SCSI_G_NCR5380_MEM */
> @@ -558,7 +567,7 @@ static inline int NCR5380_pread(struct Scsi_Host *instance, unsigned char *dst,
>  	}
>  
>  	if (blocks) {
> -		while (NCR5380_read(C400_CONTROL_STATUS_REG) & CSR_HOST_BUF_NOT_RDY)
> +		while (NCR5380_read(hostdata->c400_ctl_status) & CSR_HOST_BUF_NOT_RDY)
>  		{
>  			// FIXME - no timeout
>  		}
> @@ -567,7 +576,7 @@ static inline int NCR5380_pread(struct Scsi_Host *instance, unsigned char *dst,
>  		{
>  			int i;	
>  			for (i = 0; i < 128; i++)
> -				dst[start + i] = NCR5380_read(C400_HOST_BUFFER);
> +				dst[start + i] = NCR5380_read(hostdata->c400_host_buf);
>  		}
>  #else
>  		/* implies SCSI_G_NCR5380_MEM */
> @@ -578,7 +587,7 @@ static inline int NCR5380_pread(struct Scsi_Host *instance, unsigned char *dst,
>  		blocks--;
>  	}
>  
> -	if (!(NCR5380_read(C400_CONTROL_STATUS_REG) & CSR_GATED_53C80_IRQ))
> +	if (!(NCR5380_read(hostdata->c400_ctl_status) & CSR_GATED_53C80_IRQ))
>  		printk("53C400r: no 53C80 gated irq after transfer");
>  
>  #if 0
> @@ -586,7 +595,7 @@ static inline int NCR5380_pread(struct Scsi_Host *instance, unsigned char *dst,
>  	 *	DON'T DO THIS - THEY NEVER ARRIVE!
>  	 */
>  	printk("53C400r: Waiting for 53C80 registers\n");
> -	while (NCR5380_read(C400_CONTROL_STATUS_REG) & CSR_53C80_REG)
> +	while (NCR5380_read(hostdata->c400_ctl_status) & CSR_53C80_REG)
>  		;
>  #endif
>  	if (!(NCR5380_read(BUS_AND_STATUS_REG) & BASR_END_DMA_TRANSFER))
> @@ -607,31 +616,29 @@ static inline int NCR5380_pread(struct Scsi_Host *instance, unsigned char *dst,
>  
>  static inline int NCR5380_pwrite(struct Scsi_Host *instance, unsigned char *src, int len)
>  {
> -#ifdef SCSI_G_NCR5380_MEM
>  	struct NCR5380_hostdata *hostdata = shost_priv(instance);
> -#endif
>  	int blocks = len / 128;
>  	int start = 0;
>  	int bl;
>  	int i;
>  
> -	NCR5380_write(C400_CONTROL_STATUS_REG, CSR_BASE);
> -	NCR5380_write(C400_BLOCK_COUNTER_REG, blocks);
> +	NCR5380_write(hostdata->c400_ctl_status, CSR_BASE);
> +	NCR5380_write(hostdata->c400_blk_cnt, blocks);
>  	while (1) {
> -		if (NCR5380_read(C400_CONTROL_STATUS_REG) & CSR_GATED_53C80_IRQ) {
> +		if (NCR5380_read(hostdata->c400_ctl_status) & CSR_GATED_53C80_IRQ) {
>  			printk(KERN_ERR "53C400w: Got 53C80_IRQ start=%d, blocks=%d\n", start, blocks);
>  			return -1;
>  		}
>  
> -		if ((bl = NCR5380_read(C400_BLOCK_COUNTER_REG)) == 0) {
> +		if ((bl = NCR5380_read(hostdata->c400_blk_cnt)) == 0) {
>  			break;
>  		}
> -		while (NCR5380_read(C400_CONTROL_STATUS_REG) & CSR_HOST_BUF_NOT_RDY)
> +		while (NCR5380_read(hostdata->c400_ctl_status) & CSR_HOST_BUF_NOT_RDY)
>  			; // FIXME - timeout
>  #ifndef SCSI_G_NCR5380_MEM
>  		{
>  			for (i = 0; i < 128; i++)
> -				NCR5380_write(C400_HOST_BUFFER, src[start + i]);
> +				NCR5380_write(hostdata->c400_host_buf, src[start + i]);
>  		}
>  #else
>  		/* implies SCSI_G_NCR5380_MEM */
> @@ -642,13 +649,13 @@ static inline int NCR5380_pwrite(struct Scsi_Host *instance, unsigned char *src,
>  		blocks--;
>  	}
>  	if (blocks) {
> -		while (NCR5380_read(C400_CONTROL_STATUS_REG) & CSR_HOST_BUF_NOT_RDY)
> +		while (NCR5380_read(hostdata->c400_ctl_status) & CSR_HOST_BUF_NOT_RDY)
>  			; // FIXME - no timeout
>  
>  #ifndef SCSI_G_NCR5380_MEM
>  		{
>  			for (i = 0; i < 128; i++)
> -				NCR5380_write(C400_HOST_BUFFER, src[start + i]);
> +				NCR5380_write(hostdata->c400_host_buf, src[start + i]);
>  		}
>  #else
>  		/* implies SCSI_G_NCR5380_MEM */
> @@ -661,7 +668,7 @@ static inline int NCR5380_pwrite(struct Scsi_Host *instance, unsigned char *src,
>  
>  #if 0
>  	printk("53C400w: waiting for registers to be available\n");
> -	THEY NEVER DO ! while (NCR5380_read(C400_CONTROL_STATUS_REG) & CSR_53C80_REG);
> +	THEY NEVER DO ! while (NCR5380_read(hostdata->c400_ctl_status) & CSR_53C80_REG);
>  	printk("53C400w: Got em\n");
>  #endif
>  
> @@ -669,7 +676,7 @@ static inline int NCR5380_pwrite(struct Scsi_Host *instance, unsigned char *src,
>  	/* All documentation says to check for this. Maybe my hardware is too
>  	 * fast. Waiting for it seems to work fine! KLL
>  	 */
> -	while (!(i = NCR5380_read(C400_CONTROL_STATUS_REG) & CSR_GATED_53C80_IRQ))
> +	while (!(i = NCR5380_read(hostdata->c400_ctl_status) & CSR_GATED_53C80_IRQ))
>  		;	// FIXME - no timeout
>  
>  	/*
> diff --git a/drivers/scsi/g_NCR5380.h b/drivers/scsi/g_NCR5380.h
> index fd201e9..633edd0 100644
> --- a/drivers/scsi/g_NCR5380.h
> +++ b/drivers/scsi/g_NCR5380.h
> @@ -29,7 +29,6 @@
>  
>  #define NCR5380_map_type int
>  #define NCR5380_map_name port
> -#define NCR53C400_register_offset 0
>  
>  #ifdef CONFIG_SCSI_GENERIC_NCR53C400
>  #define NCR5380_region_size 16
> @@ -42,7 +41,10 @@
>  #define NCR5380_write(reg, value) \
>  	outb(value, instance->io_port + (reg))
>  
> -#define NCR5380_implementation_fields /* none */
> +#define NCR5380_implementation_fields \
> +	int c400_ctl_status;\
> +	int c400_blk_cnt;\
> +	int c400_host_buf;
>  
>  #else 
>  /* therefore SCSI_G_NCR5380_MEM */

A space before the backslash would be more consistent.

> @@ -50,7 +52,6 @@
>  
>  #define NCR5380_map_type unsigned long
>  #define NCR5380_map_name base
> -#define NCR53C400_register_offset 0x108
>  #define NCR53C400_mem_base 0x3880
>  #define NCR53C400_host_buffer 0x3900
>  #define NCR5380_region_size 0x3a00
> @@ -63,7 +64,10 @@
>  	       NCR53C400_mem_base + (reg))
>  
>  #define NCR5380_implementation_fields \
> -    void __iomem *iomem;
> +	void __iomem *iomem;\
> +	int c400_ctl_status;\
> +	int c400_blk_cnt;\
> +	int c400_host_buf;
>  
>  #endif
>  

Same here.

-- 

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

* Re: [RFC PATCH 74/71] ncr5380: Enable PDMA for NCR53C400A
  2015-11-29  9:39 ` [RFC PATCH 74/71] ncr5380: Enable PDMA for NCR53C400A Ondrej Zary
@ 2015-11-30 11:52   ` Finn Thain
  2015-11-30 12:04   ` Finn Thain
  1 sibling, 0 replies; 268+ messages in thread
From: Finn Thain @ 2015-11-30 11:52 UTC (permalink / raw)
  To: Ondrej Zary; +Cc: Michael Schmitz, linux-m68k, linux-scsi, linux-kernel


On Sun, 29 Nov 2015, Ondrej Zary wrote:

> Add I/O register mapping for NCR53C400A and enable PDMA mode to
> improve performance and fix non-working IRQ.
> 
> Tested with HP C2502 (and user-space enabler).
> 
> Signed-off-by: Ondrej Zary <linux@rainbow-software.org>
> ---
>  drivers/scsi/g_NCR5380.c |   11 ++++++++++-
>  1 file changed, 10 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/scsi/g_NCR5380.c b/drivers/scsi/g_NCR5380.c
> index ce444da..c3abe48 100644
> --- a/drivers/scsi/g_NCR5380.c
> +++ b/drivers/scsi/g_NCR5380.c
> @@ -324,7 +324,10 @@ static int __init generic_NCR5380_detect(struct scsi_host_template *tpnt)
>  #endif
>  			break;
>  		case BOARD_NCR53C400A:
> +			flags = FLAG_NO_DMA_FIXUP;
> +#ifndef PSEUDO_DMA
>  			flags = FLAG_NO_PSEUDO_DMA;
> +#endif

FLAG_NO_PSEUDO_DMA is not tested unless defined(PSEUDO_DMA), so it 
shouldn't be set here. I know I made the same mistake in patch 8; it will 
be fixed in the next submission.

-- 

>  			ports = ncr_53c400a_ports;
>  			break;
>  		case BOARD_DTC3181E:
> @@ -412,6 +415,11 @@ static int __init generic_NCR5380_detect(struct scsi_host_template *tpnt)
>  			hostdata->c400_blk_cnt = 1;
>  			hostdata->c400_host_buf = 4;
>  		}
> +		if (overrides[current_override].board == BOARD_NCR53C400A) {
> +			hostdata->c400_ctl_status = 9;
> +			hostdata->c400_blk_cnt = 10;
> +			hostdata->c400_host_buf = 8;
> +		}
>  #else
>  		instance->base = overrides[current_override].NCR5380_map_name;
>  		hostdata->iomem = iomem;
> @@ -425,7 +433,8 @@ static int __init generic_NCR5380_detect(struct scsi_host_template *tpnt)
>  		if (NCR5380_init(instance, flags))
>  			goto out_unregister;
>  
> -		if (overrides[current_override].board == BOARD_NCR53C400)
> +		if (overrides[current_override].board == BOARD_NCR53C400 ||
> +		    overrides[current_override].board == BOARD_NCR53C400A)
>  			NCR5380_write(hostdata->c400_ctl_status, CSR_BASE);
>  
>  		NCR5380_maybe_reset_bus(instance);
> 

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

* Re: [RFC PATCH 74/71] ncr5380: Enable PDMA for NCR53C400A
  2015-11-29  9:39 ` [RFC PATCH 74/71] ncr5380: Enable PDMA for NCR53C400A Ondrej Zary
  2015-11-30 11:52   ` Finn Thain
@ 2015-11-30 12:04   ` Finn Thain
  2015-11-30 13:40     ` Ondrej Zary
  1 sibling, 1 reply; 268+ messages in thread
From: Finn Thain @ 2015-11-30 12:04 UTC (permalink / raw)
  To: Ondrej Zary; +Cc: Michael Schmitz, linux-m68k, linux-scsi, linux-kernel


On Sun, 29 Nov 2015, Ondrej Zary wrote:

> Add I/O register mapping for NCR53C400A and enable PDMA mode to
> improve performance and fix non-working IRQ.
> 

Is CONFIG_SCSI_GENERIC_NCR53C400 is still needed? Can the driver be fully 
configured at runtime now?

> Tested with HP C2502 (and user-space enabler).
> 

It would be nice if the enabler was documented.  
Documentation/scsi/g_NCR5380.txt might be a good place for that. That file 
could perhaps be updated (?) Certainly obsolete and misleading information 
should be removed if you see any.

-- 

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

* Re: [RFC PATCH 74/71] ncr5380: Enable PDMA for NCR53C400A
  2015-11-30 12:04   ` Finn Thain
@ 2015-11-30 13:40     ` Ondrej Zary
  2015-12-06  3:20       ` Finn Thain
  0 siblings, 1 reply; 268+ messages in thread
From: Ondrej Zary @ 2015-11-30 13:40 UTC (permalink / raw)
  To: Finn Thain; +Cc: Michael Schmitz, linux-m68k, linux-scsi, linux-kernel

On Monday 30 November 2015, Finn Thain wrote:
> 
> On Sun, 29 Nov 2015, Ondrej Zary wrote:
> 
> > Add I/O register mapping for NCR53C400A and enable PDMA mode to
> > improve performance and fix non-working IRQ.
> > 
> 
> Is CONFIG_SCSI_GENERIC_NCR53C400 is still needed? Can the driver be fully 
> configured at runtime now?

Things depending on CONFIG_SCSI_GENERIC_NCR53C400:

#ifdef CONFIG_SCSI_GENERIC_NCR53C400
#define PSEUDO_DMA
#endif

Defining PSEUDO_DMA should not break anything, just makes code bigger a bit. We can probably just define it always in g_NCR5380.c.


This looks weird. I don't have any card with a BIOS to test.
#ifdef CONFIG_SCSI_GENERIC_NCR53C400
#define BIOSPARAM
#define NCR5380_BIOSPARAM generic_NCR5380_biosparam
#else
#define NCR5380_BIOSPARAM NULL
#endif


This looks very wrong and should be done at runtime:
#ifdef CONFIG_SCSI_GENERIC_NCR53C400
#define NCR5380_region_size 16
#else
#define NCR5380_region_size 8
#endif


> > Tested with HP C2502 (and user-space enabler).
> > 
> 
> It would be nice if the enabler was documented.  
> Documentation/scsi/g_NCR5380.txt might be a good place for that. That file 
> could perhaps be updated (?) Certainly obsolete and misleading information 
> should be removed if you see any.
 
I'll integrate the enabler into the driver. It's like "wakeup sequence for the NCR53C400A and DTC3181E */" in g_NCR5380.c, only the magic numbers are different.

-- 
Ondrej Zary

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

* [RFC PATCH 76/71] ncr5380: Enable PDMA for DTC chips
  2015-11-18  8:34 ` Finn Thain
                   ` (76 preceding siblings ...)
  (?)
@ 2015-12-03 23:03 ` Ondrej Zary
  2015-12-04  0:12   ` Julian Calaby
                     ` (2 more replies)
  -1 siblings, 3 replies; 268+ messages in thread
From: Ondrej Zary @ 2015-12-03 23:03 UTC (permalink / raw)
  To: Finn Thain, Michael Schmitz, linux-m68k, linux-scsi, linux-kernel

Add I/O register mapping for DTC chips and enable PDMA mode.

These chips have 16-bit wide HOST BUFFER register (counter register at
offset 0x0d increments by 2 on each HOST BUFFER read).

Large PIO transfers crash at least the DTCT-436P chip (all reads result
in 0xFF) so this patch actually makes it work.

The chip also crashes when we bang the C400 host status register too
heavily after PDMA write - a small udelay is needed.

Signed-off-by: Ondrej Zary <linux@rainbow-software.org>
---
# hdparm -t --direct /dev/sdb

/dev/sdb:
 Timing O_DIRECT disk reads:   4 MB in  3.78 seconds =   1.06 MB/sec


 drivers/scsi/NCR5380.h   |    1 +
 drivers/scsi/g_NCR5380.c |   47 +++++++++++++++++++++++-----------------------
 2 files changed, 25 insertions(+), 23 deletions(-)

diff --git a/drivers/scsi/NCR5380.h b/drivers/scsi/NCR5380.h
index 5092580..e3b8149 100644
--- a/drivers/scsi/NCR5380.h
+++ b/drivers/scsi/NCR5380.h
@@ -222,6 +222,7 @@
 
 #define FLAG_NO_DMA_FIXUP		1	/* No DMA errata workarounds */
 #define FLAG_NO_PSEUDO_DMA		8	/* Inhibit DMA */
+#define FLAG_16BIT			16	/* 16-bit PDMA */
 #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 */
diff --git a/drivers/scsi/g_NCR5380.c b/drivers/scsi/g_NCR5380.c
index fae4332..04f6c29 100644
--- a/drivers/scsi/g_NCR5380.c
+++ b/drivers/scsi/g_NCR5380.c
@@ -331,7 +331,7 @@ static int __init generic_NCR5380_detect(struct scsi_host_template *tpnt)
 			ports = ncr_53c400a_ports;
 			break;
 		case BOARD_DTC3181E:
-			flags = FLAG_NO_PSEUDO_DMA;
+			flags = FLAG_NO_DMA_FIXUP | FLAG_16BIT;
 			ports = dtc_3181e_ports;
 			break;
 		}
@@ -415,7 +415,8 @@ static int __init generic_NCR5380_detect(struct scsi_host_template *tpnt)
 			hostdata->c400_blk_cnt = 1;
 			hostdata->c400_host_buf = 4;
 		}
-		if (overrides[current_override].board == BOARD_NCR53C400A) {
+		if (overrides[current_override].board == BOARD_NCR53C400A ||
+		    overrides[current_override].board == BOARD_DTC3181E) {
 			hostdata->c400_ctl_status = 9;
 			hostdata->c400_blk_cnt = 10;
 			hostdata->c400_host_buf = 8;
@@ -434,7 +435,8 @@ static int __init generic_NCR5380_detect(struct scsi_host_template *tpnt)
 			goto out_unregister;
 
 		if (overrides[current_override].board == BOARD_NCR53C400 ||
-		    overrides[current_override].board == BOARD_NCR53C400A)
+		    overrides[current_override].board == BOARD_NCR53C400A ||
+		    overrides[current_override].board == BOARD_DTC3181E)
 			NCR5380_write(hostdata->c400_ctl_status, CSR_BASE);
 
 		NCR5380_maybe_reset_bus(instance);
@@ -561,11 +563,10 @@ static inline int NCR5380_pread(struct Scsi_Host *instance, unsigned char *dst,
 		while (NCR5380_read(hostdata->c400_ctl_status) & CSR_HOST_BUF_NOT_RDY);
 
 #ifndef SCSI_G_NCR5380_MEM
-		{
-			int i;
-			for (i = 0; i < 128; i++)
-				dst[start + i] = NCR5380_read(hostdata->c400_host_buf);
-		}
+		if (hostdata->flags & FLAG_16BIT)
+			insw(instance->io_port + hostdata->c400_host_buf, dst + start, 64);
+		else
+			insb(instance->io_port + hostdata->c400_host_buf, dst + start, 128);
 #else
 		/* implies SCSI_G_NCR5380_MEM */
 		memcpy_fromio(dst + start,
@@ -582,11 +583,10 @@ static inline int NCR5380_pread(struct Scsi_Host *instance, unsigned char *dst,
 		}
 
 #ifndef SCSI_G_NCR5380_MEM
-		{
-			int i;	
-			for (i = 0; i < 128; i++)
-				dst[start + i] = NCR5380_read(hostdata->c400_host_buf);
-		}
+		if (hostdata->flags & FLAG_16BIT)
+			insw(instance->io_port + hostdata->c400_host_buf, dst + start, 64);
+		else
+			insb(instance->io_port + hostdata->c400_host_buf, dst + start, 128);
 #else
 		/* implies SCSI_G_NCR5380_MEM */
 		memcpy_fromio(dst + start,
@@ -645,10 +645,10 @@ static inline int NCR5380_pwrite(struct Scsi_Host *instance, unsigned char *src,
 		while (NCR5380_read(hostdata->c400_ctl_status) & CSR_HOST_BUF_NOT_RDY)
 			; // FIXME - timeout
 #ifndef SCSI_G_NCR5380_MEM
-		{
-			for (i = 0; i < 128; i++)
-				NCR5380_write(hostdata->c400_host_buf, src[start + i]);
-		}
+		if (hostdata->flags & FLAG_16BIT)
+			outsw(instance->io_port + hostdata->c400_host_buf, src + start, 64);
+		else
+			outsb(instance->io_port + hostdata->c400_host_buf, src + start, 128);
 #else
 		/* implies SCSI_G_NCR5380_MEM */
 		memcpy_toio(hostdata->iomem + NCR53C400_host_buffer,
@@ -660,12 +660,11 @@ static inline int NCR5380_pwrite(struct Scsi_Host *instance, unsigned char *src,
 	if (blocks) {
 		while (NCR5380_read(hostdata->c400_ctl_status) & CSR_HOST_BUF_NOT_RDY)
 			; // FIXME - no timeout
-
 #ifndef SCSI_G_NCR5380_MEM
-		{
-			for (i = 0; i < 128; i++)
-				NCR5380_write(hostdata->c400_host_buf, src[start + i]);
-		}
+		if (hostdata->flags & FLAG_16BIT)
+			outsw(instance->io_port + hostdata->c400_host_buf, src + start, 64);
+		else
+			outsb(instance->io_port + hostdata->c400_host_buf, src + start, 128);
 #else
 		/* implies SCSI_G_NCR5380_MEM */
 		memcpy_toio(hostdata->iomem + NCR53C400_host_buffer,
@@ -685,8 +684,10 @@ static inline int NCR5380_pwrite(struct Scsi_Host *instance, unsigned char *src,
 	/* All documentation says to check for this. Maybe my hardware is too
 	 * fast. Waiting for it seems to work fine! KLL
 	 */
-	while (!(i = NCR5380_read(hostdata->c400_ctl_status) & CSR_GATED_53C80_IRQ))
+	while (!(i = NCR5380_read(hostdata->c400_ctl_status) & CSR_GATED_53C80_IRQ)) {
+		udelay(4); /* DTC436 chip hangs without this */
 		;	// FIXME - no timeout
+	}
 
 	/*
 	 * I know. i is certainly != 0 here but the loop is new. See previous
-- 
Ondrej Zary


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

* [RFC PATCH 77/71] ncr5380: Fix wait for 53C80 registers registers after PDMA
  2015-11-18  8:34 ` Finn Thain
                   ` (77 preceding siblings ...)
  (?)
@ 2015-12-03 23:03 ` Ondrej Zary
  -1 siblings, 0 replies; 268+ messages in thread
From: Ondrej Zary @ 2015-12-03 23:03 UTC (permalink / raw)
  To: Finn Thain, Michael Schmitz, linux-m68k, linux-scsi, linux-kernel

The check for 53C80 registers accessibility was commented out because
it was broken (inverted). Fix and enable it.

Signed-off-by: Ondrej Zary <linux@rainbow-software.org>
---
 drivers/scsi/g_NCR5380.c |   35 +++++++----------------------------
 1 file changed, 7 insertions(+), 28 deletions(-)

diff --git a/drivers/scsi/g_NCR5380.c b/drivers/scsi/g_NCR5380.c
index 04f6c29..c5cd490 100644
--- a/drivers/scsi/g_NCR5380.c
+++ b/drivers/scsi/g_NCR5380.c
@@ -599,14 +599,10 @@ static inline int NCR5380_pread(struct Scsi_Host *instance, unsigned char *dst,
 	if (!(NCR5380_read(hostdata->c400_ctl_status) & CSR_GATED_53C80_IRQ))
 		printk("53C400r: no 53C80 gated irq after transfer");
 
-#if 0
-	/*
-	 *	DON'T DO THIS - THEY NEVER ARRIVE!
-	 */
-	printk("53C400r: Waiting for 53C80 registers\n");
-	while (NCR5380_read(hostdata->c400_ctl_status) & CSR_53C80_REG)
+	/* wait for 53C80 registers to be available */
+	while (!(NCR5380_read(hostdata->c400_ctl_status) & CSR_53C80_REG))
 		;
-#endif
+
 	if (!(NCR5380_read(BUS_AND_STATUS_REG) & BASR_END_DMA_TRANSFER))
 		printk(KERN_ERR "53C400r: no end dma signal\n");
 		
@@ -674,36 +670,19 @@ static inline int NCR5380_pwrite(struct Scsi_Host *instance, unsigned char *src,
 		blocks--;
 	}
 
-#if 0
-	printk("53C400w: waiting for registers to be available\n");
-	THEY NEVER DO ! while (NCR5380_read(hostdata->c400_ctl_status) & CSR_53C80_REG);
-	printk("53C400w: Got em\n");
-#endif
-
-	/* Let's wait for this instead - could be ugly */
-	/* All documentation says to check for this. Maybe my hardware is too
-	 * fast. Waiting for it seems to work fine! KLL
-	 */
 	while (!(i = NCR5380_read(hostdata->c400_ctl_status) & CSR_GATED_53C80_IRQ)) {
 		udelay(4); /* DTC436 chip hangs without this */
 		;	// FIXME - no timeout
 	}
 
-	/*
-	 * I know. i is certainly != 0 here but the loop is new. See previous
-	 * comment.
-	 */
-	if (i) {
-		if (!((i = NCR5380_read(BUS_AND_STATUS_REG)) & BASR_END_DMA_TRANSFER))
-			printk(KERN_ERR "53C400w: No END OF DMA bit - WHOOPS! BASR=%0x\n", i);
-	} else
-		printk(KERN_ERR "53C400w: no 53C80 gated irq after transfer (last block)\n");
+	/* wait for 53C80 registers to be available */
+	while (!(NCR5380_read(hostdata->c400_ctl_status) & CSR_53C80_REG))
+		;
 
-#if 0
 	if (!(NCR5380_read(BUS_AND_STATUS_REG) & BASR_END_DMA_TRANSFER)) {
 		printk(KERN_ERR "53C400w: no end dma signal\n");
 	}
-#endif
+
 	while (!(NCR5380_read(TARGET_COMMAND_REG) & TCR_LAST_BYTE_SENT))
 		; 	// TIMEOUT
 	return 0;
-- 
Ondrej Zary


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

* Re: [RFC PATCH 76/71] ncr5380: Enable PDMA for DTC chips
  2015-12-03 23:03 ` [RFC PATCH 76/71] ncr5380: Enable PDMA for DTC chips Ondrej Zary
@ 2015-12-04  0:12   ` Julian Calaby
  2015-12-04  8:38     ` Finn Thain
  2015-12-04  9:08   ` Finn Thain
  2015-12-04  9:20   ` Finn Thain
  2 siblings, 1 reply; 268+ messages in thread
From: Julian Calaby @ 2015-12-04  0:12 UTC (permalink / raw)
  To: Ondrej Zary
  Cc: Finn Thain, Michael Schmitz, linux-m68k, linux-scsi, linux-kernel

Hi Finn, Ondrej,

One small question:

On Fri, Dec 4, 2015 at 10:03 AM, Ondrej Zary <linux@rainbow-software.org> wrote:
> Add I/O register mapping for DTC chips and enable PDMA mode.
>
> These chips have 16-bit wide HOST BUFFER register (counter register at
> offset 0x0d increments by 2 on each HOST BUFFER read).
>
> Large PIO transfers crash at least the DTCT-436P chip (all reads result
> in 0xFF) so this patch actually makes it work.
>
> The chip also crashes when we bang the C400 host status register too
> heavily after PDMA write - a small udelay is needed.
>
> Signed-off-by: Ondrej Zary <linux@rainbow-software.org>
> ---
> # hdparm -t --direct /dev/sdb
>
> /dev/sdb:
>  Timing O_DIRECT disk reads:   4 MB in  3.78 seconds =   1.06 MB/sec
>
>
>  drivers/scsi/NCR5380.h   |    1 +
>  drivers/scsi/g_NCR5380.c |   47 +++++++++++++++++++++++-----------------------
>  2 files changed, 25 insertions(+), 23 deletions(-)
>
> diff --git a/drivers/scsi/g_NCR5380.c b/drivers/scsi/g_NCR5380.c
> index fae4332..04f6c29 100644
> --- a/drivers/scsi/g_NCR5380.c
> +++ b/drivers/scsi/g_NCR5380.c
> @@ -415,7 +415,8 @@ static int __init generic_NCR5380_detect(struct scsi_host_template *tpnt)
>                         hostdata->c400_blk_cnt = 1;
>                         hostdata->c400_host_buf = 4;
>                 }
> -               if (overrides[current_override].board == BOARD_NCR53C400A) {
> +               if (overrides[current_override].board == BOARD_NCR53C400A ||
> +                   overrides[current_override].board == BOARD_DTC3181E) {

These if statements are starting to get a bit long, would it make
sense to replace them with a flag or equivalent?

Thanks,

-- 
Julian Calaby

Email: julian.calaby@gmail.com
Profile: http://www.google.com/profiles/julian.calaby/

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

* Re: [RFC PATCH 76/71] ncr5380: Enable PDMA for DTC chips
  2015-12-04  0:12   ` Julian Calaby
@ 2015-12-04  8:38     ` Finn Thain
  2015-12-05  1:32       ` Julian Calaby
  0 siblings, 1 reply; 268+ messages in thread
From: Finn Thain @ 2015-12-04  8:38 UTC (permalink / raw)
  To: Julian Calaby
  Cc: Ondrej Zary, Michael Schmitz, linux-m68k, linux-scsi, linux-kernel


On Fri, 4 Dec 2015, Julian Calaby wrote:

> > -               if (overrides[current_override].board == BOARD_NCR53C400A) {
> > +               if (overrides[current_override].board == BOARD_NCR53C400A ||
> > +                   overrides[current_override].board == BOARD_DTC3181E) {
> 
> These if statements are starting to get a bit long, would it make
> sense to replace them with a flag or equivalent?

To what end? Shorter lines? As in,

	if (board_is_ncr53c400a || board_is_dtc3181e) {
		/* ... */
	}

I suppose that could be an improvement if new flags would entirely replace 
the override.board struct member and the existing switch statement,

	switch (overrides[current_override].board) {
		/* ... */
	}

Or maybe you meant testing a new flag something like this,

	if (hostdata->ncr53c400_compatible) {
		/* ... */
	}

If your concern is the Don't Repeat Yourself rule, I'm not sure that new 
flag would get tested more than once (?) And it would still have to be 
assigned using an "objectionably" long expression, e.g.

	hostdata->ncr53c400_compatible =
		overrides[current_override].board == BOARD_NCR53C400 ||
		overrides[current_override].board == BOARD_NCR53C400A ||
		overrides[current_override].board == BOARD_DTC3181E;

Rather than add new flags, perhaps a 'switch' statement instead of an 'if' 
statement would be shorter (if the size of the expression is the problem).

-- 

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

* Re: [RFC PATCH 76/71] ncr5380: Enable PDMA for DTC chips
  2015-12-03 23:03 ` [RFC PATCH 76/71] ncr5380: Enable PDMA for DTC chips Ondrej Zary
  2015-12-04  0:12   ` Julian Calaby
@ 2015-12-04  9:08   ` Finn Thain
  2015-12-04  9:32     ` Ondrej Zary
  2015-12-04  9:20   ` Finn Thain
  2 siblings, 1 reply; 268+ messages in thread
From: Finn Thain @ 2015-12-04  9:08 UTC (permalink / raw)
  To: Ondrej Zary; +Cc: Michael Schmitz, linux-m68k, linux-scsi, linux-kernel


On Fri, 4 Dec 2015, Ondrej Zary wrote:

> Add I/O register mapping for DTC chips and enable PDMA mode.
> 
> These chips have 16-bit wide HOST BUFFER register (counter register at 
> offset 0x0d increments by 2 on each HOST BUFFER read).
> 
> Large PIO transfers crash at least the DTCT-436P chip (all reads result 
> in 0xFF) so this patch actually makes it work.
> 
> The chip also crashes when we bang the C400 host status register too
> heavily after PDMA write - a small udelay is needed.
> 
> Signed-off-by: Ondrej Zary <linux@rainbow-software.org>
> ---
> # hdparm -t --direct /dev/sdb
> 
> /dev/sdb:
>  Timing O_DIRECT disk reads:   4 MB in  3.78 seconds =   1.06 MB/sec
> 
> 
>  drivers/scsi/NCR5380.h   |    1 +
>  drivers/scsi/g_NCR5380.c |   47 +++++++++++++++++++++++-----------------------
>  2 files changed, 25 insertions(+), 23 deletions(-)
> 
> diff --git a/drivers/scsi/NCR5380.h b/drivers/scsi/NCR5380.h
> index 5092580..e3b8149 100644
> --- a/drivers/scsi/NCR5380.h
> +++ b/drivers/scsi/NCR5380.h
> @@ -222,6 +222,7 @@
>  
>  #define FLAG_NO_DMA_FIXUP		1	/* No DMA errata workarounds */
>  #define FLAG_NO_PSEUDO_DMA		8	/* Inhibit DMA */
> +#define FLAG_16BIT			16	/* 16-bit PDMA */

Can we give this a better name? FLAG_16BIT could be taken to mean "16-bit 
ISA card" but do we really want a flag for that? How about 
FLAG_16BIT_BUF_REG or FLAG_WORD_IO_BUF?

All active flags appear in the console log, thanks to prepare_info(). It 
might be helpful to include this one; FLAG_DTC3181E is likely to 
disappear.

-- 

>  #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 */
> diff --git a/drivers/scsi/g_NCR5380.c b/drivers/scsi/g_NCR5380.c
> index fae4332..04f6c29 100644
> --- a/drivers/scsi/g_NCR5380.c
> +++ b/drivers/scsi/g_NCR5380.c
> @@ -331,7 +331,7 @@ static int __init generic_NCR5380_detect(struct scsi_host_template *tpnt)
>  			ports = ncr_53c400a_ports;
>  			break;
>  		case BOARD_DTC3181E:
> -			flags = FLAG_NO_PSEUDO_DMA;
> +			flags = FLAG_NO_DMA_FIXUP | FLAG_16BIT;
>  			ports = dtc_3181e_ports;
>  			break;
>  		}
> @@ -415,7 +415,8 @@ static int __init generic_NCR5380_detect(struct scsi_host_template *tpnt)
>  			hostdata->c400_blk_cnt = 1;
>  			hostdata->c400_host_buf = 4;
>  		}
> -		if (overrides[current_override].board == BOARD_NCR53C400A) {
> +		if (overrides[current_override].board == BOARD_NCR53C400A ||
> +		    overrides[current_override].board == BOARD_DTC3181E) {
>  			hostdata->c400_ctl_status = 9;
>  			hostdata->c400_blk_cnt = 10;
>  			hostdata->c400_host_buf = 8;
> @@ -434,7 +435,8 @@ static int __init generic_NCR5380_detect(struct scsi_host_template *tpnt)
>  			goto out_unregister;
>  
>  		if (overrides[current_override].board == BOARD_NCR53C400 ||
> -		    overrides[current_override].board == BOARD_NCR53C400A)
> +		    overrides[current_override].board == BOARD_NCR53C400A ||
> +		    overrides[current_override].board == BOARD_DTC3181E)
>  			NCR5380_write(hostdata->c400_ctl_status, CSR_BASE);
>  
>  		NCR5380_maybe_reset_bus(instance);
> @@ -561,11 +563,10 @@ static inline int NCR5380_pread(struct Scsi_Host *instance, unsigned char *dst,
>  		while (NCR5380_read(hostdata->c400_ctl_status) & CSR_HOST_BUF_NOT_RDY);
>  
>  #ifndef SCSI_G_NCR5380_MEM
> -		{
> -			int i;
> -			for (i = 0; i < 128; i++)
> -				dst[start + i] = NCR5380_read(hostdata->c400_host_buf);
> -		}
> +		if (hostdata->flags & FLAG_16BIT)
> +			insw(instance->io_port + hostdata->c400_host_buf, dst + start, 64);
> +		else
> +			insb(instance->io_port + hostdata->c400_host_buf, dst + start, 128);
>  #else
>  		/* implies SCSI_G_NCR5380_MEM */
>  		memcpy_fromio(dst + start,
> @@ -582,11 +583,10 @@ static inline int NCR5380_pread(struct Scsi_Host *instance, unsigned char *dst,
>  		}
>  
>  #ifndef SCSI_G_NCR5380_MEM
> -		{
> -			int i;	
> -			for (i = 0; i < 128; i++)
> -				dst[start + i] = NCR5380_read(hostdata->c400_host_buf);
> -		}
> +		if (hostdata->flags & FLAG_16BIT)
> +			insw(instance->io_port + hostdata->c400_host_buf, dst + start, 64);
> +		else
> +			insb(instance->io_port + hostdata->c400_host_buf, dst + start, 128);
>  #else
>  		/* implies SCSI_G_NCR5380_MEM */
>  		memcpy_fromio(dst + start,
> @@ -645,10 +645,10 @@ static inline int NCR5380_pwrite(struct Scsi_Host *instance, unsigned char *src,
>  		while (NCR5380_read(hostdata->c400_ctl_status) & CSR_HOST_BUF_NOT_RDY)
>  			; // FIXME - timeout
>  #ifndef SCSI_G_NCR5380_MEM
> -		{
> -			for (i = 0; i < 128; i++)
> -				NCR5380_write(hostdata->c400_host_buf, src[start + i]);
> -		}
> +		if (hostdata->flags & FLAG_16BIT)
> +			outsw(instance->io_port + hostdata->c400_host_buf, src + start, 64);
> +		else
> +			outsb(instance->io_port + hostdata->c400_host_buf, src + start, 128);
>  #else
>  		/* implies SCSI_G_NCR5380_MEM */
>  		memcpy_toio(hostdata->iomem + NCR53C400_host_buffer,
> @@ -660,12 +660,11 @@ static inline int NCR5380_pwrite(struct Scsi_Host *instance, unsigned char *src,
>  	if (blocks) {
>  		while (NCR5380_read(hostdata->c400_ctl_status) & CSR_HOST_BUF_NOT_RDY)
>  			; // FIXME - no timeout
> -
>  #ifndef SCSI_G_NCR5380_MEM
> -		{
> -			for (i = 0; i < 128; i++)
> -				NCR5380_write(hostdata->c400_host_buf, src[start + i]);
> -		}
> +		if (hostdata->flags & FLAG_16BIT)
> +			outsw(instance->io_port + hostdata->c400_host_buf, src + start, 64);
> +		else
> +			outsb(instance->io_port + hostdata->c400_host_buf, src + start, 128);
>  #else
>  		/* implies SCSI_G_NCR5380_MEM */
>  		memcpy_toio(hostdata->iomem + NCR53C400_host_buffer,
> @@ -685,8 +684,10 @@ static inline int NCR5380_pwrite(struct Scsi_Host *instance, unsigned char *src,
>  	/* All documentation says to check for this. Maybe my hardware is too
>  	 * fast. Waiting for it seems to work fine! KLL
>  	 */
> -	while (!(i = NCR5380_read(hostdata->c400_ctl_status) & CSR_GATED_53C80_IRQ))
> +	while (!(i = NCR5380_read(hostdata->c400_ctl_status) & CSR_GATED_53C80_IRQ)) {
> +		udelay(4); /* DTC436 chip hangs without this */
>  		;	// FIXME - no timeout
> +	}
>  
>  	/*
>  	 * I know. i is certainly != 0 here but the loop is new. See previous
> 

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

* Re: [RFC PATCH 76/71] ncr5380: Enable PDMA for DTC chips
  2015-12-03 23:03 ` [RFC PATCH 76/71] ncr5380: Enable PDMA for DTC chips Ondrej Zary
  2015-12-04  0:12   ` Julian Calaby
  2015-12-04  9:08   ` Finn Thain
@ 2015-12-04  9:20   ` Finn Thain
  2 siblings, 0 replies; 268+ messages in thread
From: Finn Thain @ 2015-12-04  9:20 UTC (permalink / raw)
  To: Ondrej Zary; +Cc: Michael Schmitz, linux-m68k, linux-scsi, linux-kernel


On Fri, 4 Dec 2015, Ondrej Zary wrote:

> @@ -685,8 +684,10 @@ static inline int NCR5380_pwrite(struct Scsi_Host *instance, unsigned char *src,
>  	/* All documentation says to check for this. Maybe my hardware is too
>  	 * fast. Waiting for it seems to work fine! KLL
>  	 */
> -	while (!(i = NCR5380_read(hostdata->c400_ctl_status) & CSR_GATED_53C80_IRQ))
> +	while (!(i = NCR5380_read(hostdata->c400_ctl_status) & CSR_GATED_53C80_IRQ)) {
> +		udelay(4); /* DTC436 chip hangs without this */
>  		;	// FIXME - no timeout
> +	}
>  
>  	/*
>  	 * I know. i is certainly != 0 here but the loop is new. See previous
> 

Given that you've added braces, the redundant semicolon can be removed.

-- 

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

* Re: [RFC PATCH 76/71] ncr5380: Enable PDMA for DTC chips
  2015-12-04  9:08   ` Finn Thain
@ 2015-12-04  9:32     ` Ondrej Zary
  0 siblings, 0 replies; 268+ messages in thread
From: Ondrej Zary @ 2015-12-04  9:32 UTC (permalink / raw)
  To: Finn Thain; +Cc: Michael Schmitz, linux-m68k, linux-scsi, linux-kernel

On Friday 04 December 2015, Finn Thain wrote:
> 
> On Fri, 4 Dec 2015, Ondrej Zary wrote:
> 
> > Add I/O register mapping for DTC chips and enable PDMA mode.
> > 
> > These chips have 16-bit wide HOST BUFFER register (counter register at 
> > offset 0x0d increments by 2 on each HOST BUFFER read).
> > 
> > Large PIO transfers crash at least the DTCT-436P chip (all reads result 
> > in 0xFF) so this patch actually makes it work.
> > 
> > The chip also crashes when we bang the C400 host status register too
> > heavily after PDMA write - a small udelay is needed.
> > 
> > Signed-off-by: Ondrej Zary <linux@rainbow-software.org>
> > ---
> > # hdparm -t --direct /dev/sdb
> > 
> > /dev/sdb:
> >  Timing O_DIRECT disk reads:   4 MB in  3.78 seconds =   1.06 MB/sec
> > 
> > 
> >  drivers/scsi/NCR5380.h   |    1 +
> >  drivers/scsi/g_NCR5380.c |   47 +++++++++++++++++++++++-----------------------
> >  2 files changed, 25 insertions(+), 23 deletions(-)
> > 
> > diff --git a/drivers/scsi/NCR5380.h b/drivers/scsi/NCR5380.h
> > index 5092580..e3b8149 100644
> > --- a/drivers/scsi/NCR5380.h
> > +++ b/drivers/scsi/NCR5380.h
> > @@ -222,6 +222,7 @@
> >  
> >  #define FLAG_NO_DMA_FIXUP		1	/* No DMA errata workarounds */
> >  #define FLAG_NO_PSEUDO_DMA		8	/* Inhibit DMA */
> > +#define FLAG_16BIT			16	/* 16-bit PDMA */
> 
> Can we give this a better name? FLAG_16BIT could be taken to mean "16-bit 
> ISA card" but do we really want a flag for that? How about 
> FLAG_16BIT_BUF_REG or FLAG_WORD_IO_BUF?
> 
> All active flags appear in the console log, thanks to prepare_info(). It 
> might be helpful to include this one; FLAG_DTC3181E is likely to 
> disappear.

Thinking more about this, we can probably detect the host buffer register
width instead of adding another flag. Read the counter, then read once from
the host buffer and read the counter again to see if it increments by 1 or 2.
Or maybe even 4 for PCI cards.

-- 
Ondrej Zary

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

* [PATCH 73/71] ncr5380: Use runtime register mapping
  2015-11-18  8:34 ` Finn Thain
                   ` (78 preceding siblings ...)
  (?)
@ 2015-12-04 21:00 ` Ondrej Zary
  2015-12-06  3:39   ` Finn Thain
  -1 siblings, 1 reply; 268+ messages in thread
From: Ondrej Zary @ 2015-12-04 21:00 UTC (permalink / raw)
  To: Finn Thain, Michael Schmitz, linux-m68k, linux-scsi, linux-kernel

Convert compile-time C400_ register mapping to runtime mapping.
This removes the weird negative register offsets and allows adding
additional mappings.

Signed-off-by: Ondrej Zary <linux@rainbow-software.org>
---
 drivers/scsi/NCR5380.h   |   13 +---------
 drivers/scsi/g_NCR5380.c |   61 ++++++++++++++++++++++++++--------------------
 drivers/scsi/g_NCR5380.h |   12 ++++++---
 3 files changed, 43 insertions(+), 43 deletions(-)

diff --git a/drivers/scsi/NCR5380.h b/drivers/scsi/NCR5380.h
index 36779df..923db6c 100644
--- a/drivers/scsi/NCR5380.h
+++ b/drivers/scsi/NCR5380.h
@@ -163,8 +163,7 @@
 /* Write any value to this register to start an ini mode DMA receive */
 #define START_DMA_INITIATOR_RECEIVE_REG 7	/* wo */
 
-#define C400_CONTROL_STATUS_REG NCR53C400_register_offset-8	/* rw */
-
+/* NCR 53C400(A) Control Status Register bits: */
 #define CSR_RESET              0x80	/* wo  Resets 53c400 */
 #define CSR_53C80_REG          0x80	/* ro  5380 registers busy */
 #define CSR_TRANS_DIR          0x40	/* rw  Data transfer direction */
@@ -181,16 +180,6 @@
 #define CSR_BASE CSR_53C80_INTR
 #endif
 
-/* Number of 128-byte blocks to be transferred */
-#define C400_BLOCK_COUNTER_REG   NCR53C400_register_offset-7	/* rw */
-
-/* Resume transfer after disconnect */
-#define C400_RESUME_TRANSFER_REG NCR53C400_register_offset-6	/* wo */
-
-/* Access to host buffer stack */
-#define C400_HOST_BUFFER         NCR53C400_register_offset-4	/* rw */
-
-
 /* Note : PHASE_* macros are based on the values of the STATUS register */
 #define PHASE_MASK 	(SR_MSG | SR_CD | SR_IO)
 
diff --git a/drivers/scsi/g_NCR5380.c b/drivers/scsi/g_NCR5380.c
index a9a237f..ce444da 100644
--- a/drivers/scsi/g_NCR5380.c
+++ b/drivers/scsi/g_NCR5380.c
@@ -253,6 +253,7 @@ static int __init generic_NCR5380_detect(struct scsi_host_template *tpnt)
 	};
 	int flags;
 	struct Scsi_Host *instance;
+	struct NCR5380_hostdata *hostdata;
 #ifdef SCSI_G_NCR5380_MEM
 	unsigned long base;
 	void __iomem *iomem;
@@ -395,6 +396,7 @@ static int __init generic_NCR5380_detect(struct scsi_host_template *tpnt)
 		instance = scsi_register(tpnt, sizeof(struct NCR5380_hostdata));
 		if (instance == NULL)
 			goto out_release;
+		hostdata = shost_priv(instance);
 
 #ifndef SCSI_G_NCR5380_MEM
 		instance->io_port = overrides[current_override].NCR5380_map_name;
@@ -404,18 +406,27 @@ static int __init generic_NCR5380_detect(struct scsi_host_template *tpnt)
 		 * On NCR53C400 boards, NCR5380 registers are mapped 8 past
 		 * the base address.
 		 */
-		if (overrides[current_override].board == BOARD_NCR53C400)
+		if (overrides[current_override].board == BOARD_NCR53C400) {
 			instance->io_port += 8;
+			hostdata->c400_ctl_status = 0;
+			hostdata->c400_blk_cnt = 1;
+			hostdata->c400_host_buf = 4;
+		}
 #else
 		instance->base = overrides[current_override].NCR5380_map_name;
-		((struct NCR5380_hostdata *)instance->hostdata)->iomem = iomem;
+		hostdata->iomem = iomem;
+		if (overrides[current_override].board == BOARD_NCR53C400) {
+			hostdata->c400_ctl_status = 0x100;
+			hostdata->c400_blk_cnt = 0x101;
+			hostdata->c400_host_buf = 0x104;
+		}
 #endif
 
 		if (NCR5380_init(instance, flags))
 			goto out_unregister;
 
 		if (overrides[current_override].board == BOARD_NCR53C400)
-			NCR5380_write(C400_CONTROL_STATUS_REG, CSR_BASE);
+			NCR5380_write(hostdata->c400_ctl_status, CSR_BASE);
 
 		NCR5380_maybe_reset_bus(instance);
 
@@ -523,30 +534,28 @@ generic_NCR5380_biosparam(struct scsi_device *sdev, struct block_device *bdev,
  
 static inline int NCR5380_pread(struct Scsi_Host *instance, unsigned char *dst, int len)
 {
-#ifdef SCSI_G_NCR5380_MEM
 	struct NCR5380_hostdata *hostdata = shost_priv(instance);
-#endif
 	int blocks = len / 128;
 	int start = 0;
 	int bl;
 
-	NCR5380_write(C400_CONTROL_STATUS_REG, CSR_BASE | CSR_TRANS_DIR);
-	NCR5380_write(C400_BLOCK_COUNTER_REG, blocks);
+	NCR5380_write(hostdata->c400_ctl_status, CSR_BASE | CSR_TRANS_DIR);
+	NCR5380_write(hostdata->c400_blk_cnt, blocks);
 	while (1) {
-		if ((bl = NCR5380_read(C400_BLOCK_COUNTER_REG)) == 0) {
+		if ((bl = NCR5380_read(hostdata->c400_blk_cnt)) == 0) {
 			break;
 		}
-		if (NCR5380_read(C400_CONTROL_STATUS_REG) & CSR_GATED_53C80_IRQ) {
+		if (NCR5380_read(hostdata->c400_ctl_status) & CSR_GATED_53C80_IRQ) {
 			printk(KERN_ERR "53C400r: Got 53C80_IRQ start=%d, blocks=%d\n", start, blocks);
 			return -1;
 		}
-		while (NCR5380_read(C400_CONTROL_STATUS_REG) & CSR_HOST_BUF_NOT_RDY);
+		while (NCR5380_read(hostdata->c400_ctl_status) & CSR_HOST_BUF_NOT_RDY);
 
 #ifndef SCSI_G_NCR5380_MEM
 		{
 			int i;
 			for (i = 0; i < 128; i++)
-				dst[start + i] = NCR5380_read(C400_HOST_BUFFER);
+				dst[start + i] = NCR5380_read(hostdata->c400_host_buf);
 		}
 #else
 		/* implies SCSI_G_NCR5380_MEM */
@@ -558,7 +567,7 @@ static inline int NCR5380_pread(struct Scsi_Host *instance, unsigned char *dst,
 	}
 
 	if (blocks) {
-		while (NCR5380_read(C400_CONTROL_STATUS_REG) & CSR_HOST_BUF_NOT_RDY)
+		while (NCR5380_read(hostdata->c400_ctl_status) & CSR_HOST_BUF_NOT_RDY)
 		{
 			// FIXME - no timeout
 		}
@@ -567,7 +576,7 @@ static inline int NCR5380_pread(struct Scsi_Host *instance, unsigned char *dst,
 		{
 			int i;	
 			for (i = 0; i < 128; i++)
-				dst[start + i] = NCR5380_read(C400_HOST_BUFFER);
+				dst[start + i] = NCR5380_read(hostdata->c400_host_buf);
 		}
 #else
 		/* implies SCSI_G_NCR5380_MEM */
@@ -578,7 +587,7 @@ static inline int NCR5380_pread(struct Scsi_Host *instance, unsigned char *dst,
 		blocks--;
 	}
 
-	if (!(NCR5380_read(C400_CONTROL_STATUS_REG) & CSR_GATED_53C80_IRQ))
+	if (!(NCR5380_read(hostdata->c400_ctl_status) & CSR_GATED_53C80_IRQ))
 		printk("53C400r: no 53C80 gated irq after transfer");
 
 #if 0
@@ -586,7 +595,7 @@ static inline int NCR5380_pread(struct Scsi_Host *instance, unsigned char *dst,
 	 *	DON'T DO THIS - THEY NEVER ARRIVE!
 	 */
 	printk("53C400r: Waiting for 53C80 registers\n");
-	while (NCR5380_read(C400_CONTROL_STATUS_REG) & CSR_53C80_REG)
+	while (NCR5380_read(hostdata->c400_ctl_status) & CSR_53C80_REG)
 		;
 #endif
 	if (!(NCR5380_read(BUS_AND_STATUS_REG) & BASR_END_DMA_TRANSFER))
@@ -607,31 +616,29 @@ static inline int NCR5380_pread(struct Scsi_Host *instance, unsigned char *dst,
 
 static inline int NCR5380_pwrite(struct Scsi_Host *instance, unsigned char *src, int len)
 {
-#ifdef SCSI_G_NCR5380_MEM
 	struct NCR5380_hostdata *hostdata = shost_priv(instance);
-#endif
 	int blocks = len / 128;
 	int start = 0;
 	int bl;
 	int i;
 
-	NCR5380_write(C400_CONTROL_STATUS_REG, CSR_BASE);
-	NCR5380_write(C400_BLOCK_COUNTER_REG, blocks);
+	NCR5380_write(hostdata->c400_ctl_status, CSR_BASE);
+	NCR5380_write(hostdata->c400_blk_cnt, blocks);
 	while (1) {
-		if (NCR5380_read(C400_CONTROL_STATUS_REG) & CSR_GATED_53C80_IRQ) {
+		if (NCR5380_read(hostdata->c400_ctl_status) & CSR_GATED_53C80_IRQ) {
 			printk(KERN_ERR "53C400w: Got 53C80_IRQ start=%d, blocks=%d\n", start, blocks);
 			return -1;
 		}
 
-		if ((bl = NCR5380_read(C400_BLOCK_COUNTER_REG)) == 0) {
+		if ((bl = NCR5380_read(hostdata->c400_blk_cnt)) == 0) {
 			break;
 		}
-		while (NCR5380_read(C400_CONTROL_STATUS_REG) & CSR_HOST_BUF_NOT_RDY)
+		while (NCR5380_read(hostdata->c400_ctl_status) & CSR_HOST_BUF_NOT_RDY)
 			; // FIXME - timeout
 #ifndef SCSI_G_NCR5380_MEM
 		{
 			for (i = 0; i < 128; i++)
-				NCR5380_write(C400_HOST_BUFFER, src[start + i]);
+				NCR5380_write(hostdata->c400_host_buf, src[start + i]);
 		}
 #else
 		/* implies SCSI_G_NCR5380_MEM */
@@ -642,13 +649,13 @@ static inline int NCR5380_pwrite(struct Scsi_Host *instance, unsigned char *src,
 		blocks--;
 	}
 	if (blocks) {
-		while (NCR5380_read(C400_CONTROL_STATUS_REG) & CSR_HOST_BUF_NOT_RDY)
+		while (NCR5380_read(hostdata->c400_ctl_status) & CSR_HOST_BUF_NOT_RDY)
 			; // FIXME - no timeout
 
 #ifndef SCSI_G_NCR5380_MEM
 		{
 			for (i = 0; i < 128; i++)
-				NCR5380_write(C400_HOST_BUFFER, src[start + i]);
+				NCR5380_write(hostdata->c400_host_buf, src[start + i]);
 		}
 #else
 		/* implies SCSI_G_NCR5380_MEM */
@@ -661,7 +668,7 @@ static inline int NCR5380_pwrite(struct Scsi_Host *instance, unsigned char *src,
 
 #if 0
 	printk("53C400w: waiting for registers to be available\n");
-	THEY NEVER DO ! while (NCR5380_read(C400_CONTROL_STATUS_REG) & CSR_53C80_REG);
+	THEY NEVER DO ! while (NCR5380_read(hostdata->c400_ctl_status) & CSR_53C80_REG);
 	printk("53C400w: Got em\n");
 #endif
 
@@ -669,7 +676,7 @@ static inline int NCR5380_pwrite(struct Scsi_Host *instance, unsigned char *src,
 	/* All documentation says to check for this. Maybe my hardware is too
 	 * fast. Waiting for it seems to work fine! KLL
 	 */
-	while (!(i = NCR5380_read(C400_CONTROL_STATUS_REG) & CSR_GATED_53C80_IRQ))
+	while (!(i = NCR5380_read(hostdata->c400_ctl_status) & CSR_GATED_53C80_IRQ))
 		;	// FIXME - no timeout
 
 	/*
diff --git a/drivers/scsi/g_NCR5380.h b/drivers/scsi/g_NCR5380.h
index fd201e9..c5e57b7 100644
--- a/drivers/scsi/g_NCR5380.h
+++ b/drivers/scsi/g_NCR5380.h
@@ -29,7 +29,6 @@
 
 #define NCR5380_map_type int
 #define NCR5380_map_name port
-#define NCR53C400_register_offset 0
 
 #ifdef CONFIG_SCSI_GENERIC_NCR53C400
 #define NCR5380_region_size 16
@@ -42,7 +41,10 @@
 #define NCR5380_write(reg, value) \
 	outb(value, instance->io_port + (reg))
 
-#define NCR5380_implementation_fields /* none */
+#define NCR5380_implementation_fields \
+	int c400_ctl_status; \
+	int c400_blk_cnt; \
+	int c400_host_buf;
 
 #else 
 /* therefore SCSI_G_NCR5380_MEM */
@@ -50,7 +52,6 @@
 
 #define NCR5380_map_type unsigned long
 #define NCR5380_map_name base
-#define NCR53C400_register_offset 0x108
 #define NCR53C400_mem_base 0x3880
 #define NCR53C400_host_buffer 0x3900
 #define NCR5380_region_size 0x3a00
@@ -63,7 +64,10 @@
 	       NCR53C400_mem_base + (reg))
 
 #define NCR5380_implementation_fields \
-    void __iomem *iomem;
+	void __iomem *iomem; \
+	int c400_ctl_status; \
+	int c400_blk_cnt; \
+	int c400_host_buf;
 
 #endif
 
-- 
Ondrej Zary


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

* [PATCH 74/71] ncr5380: Enable PDMA for NCR53C400A
  2015-11-18  8:34 ` Finn Thain
                   ` (79 preceding siblings ...)
  (?)
@ 2015-12-04 21:02 ` Ondrej Zary
  2015-12-06  3:41   ` Finn Thain
  -1 siblings, 1 reply; 268+ messages in thread
From: Ondrej Zary @ 2015-12-04 21:02 UTC (permalink / raw)
  To: Finn Thain, Michael Schmitz, linux-m68k, linux-scsi, linux-kernel

Add I/O register mapping for NCR53C400A and enable PDMA mode to
improve performance and fix non-working IRQ.

Tested with HP C2502 (and user-space enabler).

Signed-off-by: Ondrej Zary <linux@rainbow-software.org>
---
 drivers/scsi/g_NCR5380.c |   10 ++++++++--
 1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/drivers/scsi/g_NCR5380.c b/drivers/scsi/g_NCR5380.c
index ce444da..cd483c6 100644
--- a/drivers/scsi/g_NCR5380.c
+++ b/drivers/scsi/g_NCR5380.c
@@ -324,7 +324,7 @@ static int __init generic_NCR5380_detect(struct scsi_host_template *tpnt)
 #endif
 			break;
 		case BOARD_NCR53C400A:
-			flags = FLAG_NO_PSEUDO_DMA;
+			flags = FLAG_NO_DMA_FIXUP;
 			ports = ncr_53c400a_ports;
 			break;
 		case BOARD_DTC3181E:
@@ -412,6 +412,11 @@ static int __init generic_NCR5380_detect(struct scsi_host_template *tpnt)
 			hostdata->c400_blk_cnt = 1;
 			hostdata->c400_host_buf = 4;
 		}
+		if (overrides[current_override].board == BOARD_NCR53C400A) {
+			hostdata->c400_ctl_status = 9;
+			hostdata->c400_blk_cnt = 10;
+			hostdata->c400_host_buf = 8;
+		}
 #else
 		instance->base = overrides[current_override].NCR5380_map_name;
 		hostdata->iomem = iomem;
@@ -425,7 +430,8 @@ static int __init generic_NCR5380_detect(struct scsi_host_template *tpnt)
 		if (NCR5380_init(instance, flags))
 			goto out_unregister;
 
-		if (overrides[current_override].board == BOARD_NCR53C400)
+		if (overrides[current_override].board == BOARD_NCR53C400 ||
+		    overrides[current_override].board == BOARD_NCR53C400A)
 			NCR5380_write(hostdata->c400_ctl_status, CSR_BASE);
 
 		NCR5380_maybe_reset_bus(instance);
-- 
Ondrej Zary


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

* [PATCH 76/71] ncr5380: Enable PDMA for DTC chips
  2015-11-18  8:34 ` Finn Thain
                   ` (80 preceding siblings ...)
  (?)
@ 2015-12-04 21:17 ` Ondrej Zary
  2015-12-06  3:40   ` Finn Thain
  -1 siblings, 1 reply; 268+ messages in thread
From: Ondrej Zary @ 2015-12-04 21:17 UTC (permalink / raw)
  To: Finn Thain, Michael Schmitz, linux-m68k, linux-scsi, linux-kernel

Add I/O register mapping for DTC chips and enable PDMA mode.

These chips have 16-bit wide HOST BUFFER register (counter register at
offset 0x0d increments by 2 on each HOST BUFFER read). Detect it
automatically.

Large PIO transfers crash at least the DTCT-436P chip (all reads result
in 0xFF) so this patch actually makes it work.

The chip also crashes when we bang the C400 host status register too
heavily after PDMA write - a small udelay is needed.

Tested on DTCT-436P and verified that it does not break 53C400A.

Signed-off-by: Ondrej Zary <linux@rainbow-software.org>
---
 drivers/scsi/g_NCR5380.c |   59 ++++++++++++++++++++++++++++------------------
 drivers/scsi/g_NCR5380.h |    4 +++-
 2 files changed, 39 insertions(+), 24 deletions(-)

diff --git a/drivers/scsi/g_NCR5380.c b/drivers/scsi/g_NCR5380.c
index 85da3c2..9816b81 100644
--- a/drivers/scsi/g_NCR5380.c
+++ b/drivers/scsi/g_NCR5380.c
@@ -328,7 +328,7 @@ static int __init generic_NCR5380_detect(struct scsi_host_template *tpnt)
 			ports = ncr_53c400a_ports;
 			break;
 		case BOARD_DTC3181E:
-			flags = FLAG_NO_PSEUDO_DMA;
+			flags = FLAG_NO_DMA_FIXUP;
 			ports = dtc_3181e_ports;
 			break;
 		}
@@ -412,10 +412,12 @@ static int __init generic_NCR5380_detect(struct scsi_host_template *tpnt)
 			hostdata->c400_blk_cnt = 1;
 			hostdata->c400_host_buf = 4;
 		}
-		if (overrides[current_override].board == BOARD_NCR53C400A) {
+		if (overrides[current_override].board == BOARD_NCR53C400A ||
+		    overrides[current_override].board == BOARD_DTC3181E) {
 			hostdata->c400_ctl_status = 9;
 			hostdata->c400_blk_cnt = 10;
 			hostdata->c400_host_buf = 8;
+			hostdata->c400_host_idx = 13;
 		}
 #else
 		instance->base = overrides[current_override].NCR5380_map_name;
@@ -430,8 +432,20 @@ static int __init generic_NCR5380_detect(struct scsi_host_template *tpnt)
 		if (NCR5380_init(instance, flags))
 			goto out_unregister;
 
+#ifndef SCSI_G_NCR5380_MEM
+		/* read initial value of index register */
+		i = NCR5380_read(hostdata->c400_host_idx);
+		/* read something from host buffer */
+		NCR5380_read(hostdata->c400_host_buf);
+		/* I/O width = index register increment */
+		hostdata->io_width = NCR5380_read(hostdata->c400_host_idx) - i;
+		if (hostdata->io_width < 0)
+			hostdata->io_width += 128;
+#endif
+
 		if (overrides[current_override].board == BOARD_NCR53C400 ||
-		    overrides[current_override].board == BOARD_NCR53C400A)
+		    overrides[current_override].board == BOARD_NCR53C400A ||
+		    overrides[current_override].board == BOARD_DTC3181E)
 			NCR5380_write(hostdata->c400_ctl_status, CSR_BASE);
 
 		NCR5380_maybe_reset_bus(instance);
@@ -558,11 +572,10 @@ static inline int NCR5380_pread(struct Scsi_Host *instance, unsigned char *dst,
 		while (NCR5380_read(hostdata->c400_ctl_status) & CSR_HOST_BUF_NOT_RDY);
 
 #ifndef SCSI_G_NCR5380_MEM
-		{
-			int i;
-			for (i = 0; i < 128; i++)
-				dst[start + i] = NCR5380_read(hostdata->c400_host_buf);
-		}
+		if (hostdata->io_width == 2)
+			insw(instance->io_port + hostdata->c400_host_buf, dst + start, 64);
+		else
+			insb(instance->io_port + hostdata->c400_host_buf, dst + start, 128);
 #else
 		/* implies SCSI_G_NCR5380_MEM */
 		memcpy_fromio(dst + start,
@@ -579,11 +592,10 @@ static inline int NCR5380_pread(struct Scsi_Host *instance, unsigned char *dst,
 		}
 
 #ifndef SCSI_G_NCR5380_MEM
-		{
-			int i;	
-			for (i = 0; i < 128; i++)
-				dst[start + i] = NCR5380_read(hostdata->c400_host_buf);
-		}
+		if (hostdata->io_width == 2)
+			insw(instance->io_port + hostdata->c400_host_buf, dst + start, 64);
+		else
+			insb(instance->io_port + hostdata->c400_host_buf, dst + start, 128);
 #else
 		/* implies SCSI_G_NCR5380_MEM */
 		memcpy_fromio(dst + start,
@@ -642,10 +654,10 @@ static inline int NCR5380_pwrite(struct Scsi_Host *instance, unsigned char *src,
 		while (NCR5380_read(hostdata->c400_ctl_status) & CSR_HOST_BUF_NOT_RDY)
 			; // FIXME - timeout
 #ifndef SCSI_G_NCR5380_MEM
-		{
-			for (i = 0; i < 128; i++)
-				NCR5380_write(hostdata->c400_host_buf, src[start + i]);
-		}
+		if (hostdata->io_width == 2)
+			outsw(instance->io_port + hostdata->c400_host_buf, src + start, 64);
+		else
+			outsb(instance->io_port + hostdata->c400_host_buf, src + start, 128);
 #else
 		/* implies SCSI_G_NCR5380_MEM */
 		memcpy_toio(hostdata->iomem + NCR53C400_host_buffer,
@@ -657,12 +669,11 @@ static inline int NCR5380_pwrite(struct Scsi_Host *instance, unsigned char *src,
 	if (blocks) {
 		while (NCR5380_read(hostdata->c400_ctl_status) & CSR_HOST_BUF_NOT_RDY)
 			; // FIXME - no timeout
-
 #ifndef SCSI_G_NCR5380_MEM
-		{
-			for (i = 0; i < 128; i++)
-				NCR5380_write(hostdata->c400_host_buf, src[start + i]);
-		}
+		if (hostdata->io_width == 2)
+			outsw(instance->io_port + hostdata->c400_host_buf, src + start, 64);
+		else
+			outsb(instance->io_port + hostdata->c400_host_buf, src + start, 128);
 #else
 		/* implies SCSI_G_NCR5380_MEM */
 		memcpy_toio(hostdata->iomem + NCR53C400_host_buffer,
@@ -682,8 +693,10 @@ static inline int NCR5380_pwrite(struct Scsi_Host *instance, unsigned char *src,
 	/* All documentation says to check for this. Maybe my hardware is too
 	 * fast. Waiting for it seems to work fine! KLL
 	 */
-	while (!(i = NCR5380_read(hostdata->c400_ctl_status) & CSR_GATED_53C80_IRQ))
+	while (!(i = NCR5380_read(hostdata->c400_ctl_status) & CSR_GATED_53C80_IRQ)) {
+		udelay(4); /* DTC436 chip hangs without this */
 		;	// FIXME - no timeout
+	}
 
 	/*
 	 * I know. i is certainly != 0 here but the loop is new. See previous
diff --git a/drivers/scsi/g_NCR5380.h b/drivers/scsi/g_NCR5380.h
index c5e57b7..b3936aa 100644
--- a/drivers/scsi/g_NCR5380.h
+++ b/drivers/scsi/g_NCR5380.h
@@ -44,7 +44,9 @@
 #define NCR5380_implementation_fields \
 	int c400_ctl_status; \
 	int c400_blk_cnt; \
-	int c400_host_buf;
+	int c400_host_buf; \
+	int c400_host_idx; \
+	int io_width;
 
 #else 
 /* therefore SCSI_G_NCR5380_MEM */
-- 
Ondrej Zary


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

* Re: [RFC PATCH 76/71] ncr5380: Enable PDMA for DTC chips
  2015-12-04  8:38     ` Finn Thain
@ 2015-12-05  1:32       ` Julian Calaby
  2015-12-05  2:12         ` Finn Thain
  0 siblings, 1 reply; 268+ messages in thread
From: Julian Calaby @ 2015-12-05  1:32 UTC (permalink / raw)
  To: Finn Thain
  Cc: Ondrej Zary, Michael Schmitz, linux-m68k, linux-scsi, linux-kernel

Hi Finn,

On Fri, Dec 4, 2015 at 7:38 PM, Finn Thain <fthain@telegraphics.com.au> wrote:
>
> On Fri, 4 Dec 2015, Julian Calaby wrote:
>
>> > -               if (overrides[current_override].board == BOARD_NCR53C400A) {
>> > +               if (overrides[current_override].board == BOARD_NCR53C400A ||
>> > +                   overrides[current_override].board == BOARD_DTC3181E) {
>>
>> These if statements are starting to get a bit long, would it make
>> sense to replace them with a flag or equivalent?
>
> To what end? Shorter lines? As in,

Pretty much, each expression is quite long and they seem to be growing
fairly rapidly as you and Ondrej discover similar boards.

>
>         if (board_is_ncr53c400a || board_is_dtc3181e) {
>                 /* ... */
>         }
>
> I suppose that could be an improvement if new flags would entirely replace
> the override.board struct member and the existing switch statement,
>
>         switch (overrides[current_override].board) {
>                 /* ... */
>         }
>
> Or maybe you meant testing a new flag something like this,
>
>         if (hostdata->ncr53c400_compatible) {
>                 /* ... */
>         }
>
> If your concern is the Don't Repeat Yourself rule, I'm not sure that new
> flag would get tested more than once (?) And it would still have to be
> assigned using an "objectionably" long expression, e.g.
>
>         hostdata->ncr53c400_compatible =
>                 overrides[current_override].board == BOARD_NCR53C400 ||
>                 overrides[current_override].board == BOARD_NCR53C400A ||
>                 overrides[current_override].board == BOARD_DTC3181E;
>
> Rather than add new flags, perhaps a 'switch' statement instead of an 'if'
> statement would be shorter (if the size of the expression is the problem).

I think switch statements would be cleaner in this particular
instance. I was thinking something like:

if (somthing->flags & NCR53C400_COMPATIBLE) {
    /* ... */
}

but if it's only ever going to be used once, then it's pretty
pointless and switch statements are cleaner.

Thanks,

-- 
Julian Calaby

Email: julian.calaby@gmail.com
Profile: http://www.google.com/profiles/julian.calaby/

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

* Re: [RFC PATCH 76/71] ncr5380: Enable PDMA for DTC chips
  2015-12-05  1:32       ` Julian Calaby
@ 2015-12-05  2:12         ` Finn Thain
  2015-12-05  2:38           ` Julian Calaby
  0 siblings, 1 reply; 268+ messages in thread
From: Finn Thain @ 2015-12-05  2:12 UTC (permalink / raw)
  To: Julian Calaby
  Cc: Ondrej Zary, Michael Schmitz, linux-m68k, linux-scsi, linux-kernel


On Sat, 5 Dec 2015, Julian Calaby wrote:

> Hi Finn,
> 
> On Fri, Dec 4, 2015 at 7:38 PM, Finn Thain <fthain@telegraphics.com.au> wrote:
> >
> > On Fri, 4 Dec 2015, Julian Calaby wrote:
> >
> >> > -               if (overrides[current_override].board == BOARD_NCR53C400A) {
> >> > +               if (overrides[current_override].board == BOARD_NCR53C400A ||
> >> > +                   overrides[current_override].board == BOARD_DTC3181E) {
> >>
> >> These if statements are starting to get a bit long, would it make
> >> sense to replace them with a flag or equivalent?
> >
> > To what end? Shorter lines? As in,
> 
> Pretty much, each expression is quite long and they seem to be growing 
> fairly rapidly as you and Ondrej discover similar boards.

Each BOARD_* macro actually refers to a whole category of devices. No new 
boards, devices or categories of devices have been discovered.

Ondrej is enabling and/or fixing PDMA functionality for three existing 
device categories, for which the driver already has a nominally compatible 
PDMA implementation.

-- 

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

* Re: [RFC PATCH 76/71] ncr5380: Enable PDMA for DTC chips
  2015-12-05  2:12         ` Finn Thain
@ 2015-12-05  2:38           ` Julian Calaby
  0 siblings, 0 replies; 268+ messages in thread
From: Julian Calaby @ 2015-12-05  2:38 UTC (permalink / raw)
  To: Finn Thain
  Cc: Ondrej Zary, Michael Schmitz, linux-m68k, linux-scsi, linux-kernel

Hi Finn,

On Sat, Dec 5, 2015 at 1:12 PM, Finn Thain <fthain@telegraphics.com.au> wrote:
>
> On Sat, 5 Dec 2015, Julian Calaby wrote:
>
>> Hi Finn,
>>
>> On Fri, Dec 4, 2015 at 7:38 PM, Finn Thain <fthain@telegraphics.com.au> wrote:
>> >
>> > On Fri, 4 Dec 2015, Julian Calaby wrote:
>> >
>> >> > -               if (overrides[current_override].board == BOARD_NCR53C400A) {
>> >> > +               if (overrides[current_override].board == BOARD_NCR53C400A ||
>> >> > +                   overrides[current_override].board == BOARD_DTC3181E) {
>> >>
>> >> These if statements are starting to get a bit long, would it make
>> >> sense to replace them with a flag or equivalent?
>> >
>> > To what end? Shorter lines? As in,
>>
>> Pretty much, each expression is quite long and they seem to be growing
>> fairly rapidly as you and Ondrej discover similar boards.
>
> Each BOARD_* macro actually refers to a whole category of devices. No new
> boards, devices or categories of devices have been discovered.
>
> Ondrej is enabling and/or fixing PDMA functionality for three existing
> device categories, for which the driver already has a nominally compatible
> PDMA implementation.

I meant discovering boards which are similar.

Either way, I'm not sure it matters that much.

Thanks,

-- 
Julian Calaby

Email: julian.calaby@gmail.com
Profile: http://www.google.com/profiles/julian.calaby/

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

* [RFC PATCH 78/71] ncr5380: Add support for HP 53C400A-based cards (C2502)
  2015-11-18  8:34 ` Finn Thain
                   ` (81 preceding siblings ...)
  (?)
@ 2015-12-05 21:18 ` Ondrej Zary
  2015-12-06  3:39   ` Finn Thain
  -1 siblings, 1 reply; 268+ messages in thread
From: Ondrej Zary @ 2015-12-05 21:18 UTC (permalink / raw)
  To: Finn Thain, Michael Schmitz, linux-m68k, linux-scsi, linux-kernel

HP C2502 cards (based on 53C400A chips) use different magic numbers for
software-based I/O address configuration than other cards.
The configuration is also extended to allow setting the IRQ.

Move the configuration to a new function magic_configure() and move
magic the magic numbers into an array. Add new magic numbers for these
HP cards and hp_53c400a module parameter to use them.

Tested with HP C2502 and DTCT-436P.

Signed-off-by: Ondrej Zary <linux@rainbow-software.org>
---
 drivers/scsi/g_NCR5380.c |   69 +++++++++++++++++++++++++++++++++++-----------
 drivers/scsi/g_NCR5380.h |    1 +
 2 files changed, 54 insertions(+), 16 deletions(-)

diff --git a/drivers/scsi/g_NCR5380.c b/drivers/scsi/g_NCR5380.c
index 38579b0..52110e0 100644
--- a/drivers/scsi/g_NCR5380.c
+++ b/drivers/scsi/g_NCR5380.c
@@ -80,6 +80,7 @@ static int ncr_5380;
 static int ncr_53c400;
 static int ncr_53c400a;
 static int dtc_3181e;
+static int hp_53c400a;
 
 static struct override {
 	NCR5380_map_type NCR5380_map_name;
@@ -225,6 +226,26 @@ static int __init do_DTC3181E_setup(char *str)
 
 #endif
 
+#ifndef SCSI_G_NCR5380_MEM
+static void magic_configure(int idx, u8 irq, u8 magic[])
+{
+	u8 cfg = 0;
+
+	outb(magic[0], 0x779);
+	outb(magic[1], 0x379);
+	outb(magic[2], 0x379);
+	outb(magic[3], 0x379);
+	outb(magic[4], 0x379);
+
+	/* allowed IRQs for HP 53C400A */
+	if (irq != 2 && irq != 3 && irq != 4 && irq != 5 && irq != 7)
+		irq = 0;
+	if (idx >= 0 && idx <= 7)
+		cfg = 0x80 | idx | (irq << 4);
+	outb(cfg, 0x379);
+}
+#endif
+
 /**
  * 	generic_NCR5380_detect	-	look for NCR5380 controllers
  *	@tpnt: the scsi template
@@ -241,8 +262,9 @@ static int __init generic_NCR5380_detect(struct scsi_host_template *tpnt)
 	static int current_override;
 	int count;
 	unsigned int *ports;
+	u8 *magic;
 #ifndef SCSI_G_NCR5380_MEM
-	int i;
+	int i, port_idx;
 	unsigned long region_size = 16;
 #endif
 	static unsigned int __initdata ncr_53c400a_ports[] = {
@@ -251,6 +273,12 @@ static int __init generic_NCR5380_detect(struct scsi_host_template *tpnt)
 	static unsigned int __initdata dtc_3181e_ports[] = {
 		0x220, 0x240, 0x280, 0x2a0, 0x2c0, 0x300, 0x320, 0x340, 0
 	};
+	static u8 ncr_53c400a_magic[] __initdata = {
+		0x59, 0xb9, 0xc5, 0xae, 0xa6
+	};
+	static u8 hp_53c400a_magic[] __initdata = {
+		0x0f, 0x22, 0xf0, 0x20, 0x80
+	};
 	int flags;
 	struct Scsi_Host *instance;
 	struct NCR5380_hostdata *hostdata;
@@ -273,6 +301,8 @@ static int __init generic_NCR5380_detect(struct scsi_host_template *tpnt)
 		overrides[0].board = BOARD_NCR53C400A;
 	else if (dtc_3181e)
 		overrides[0].board = BOARD_DTC3181E;
+	else if (hp_53c400a)
+		overrides[0].board = BOARD_HP53C400A;
 #ifndef SCSI_G_NCR5380_MEM
 	if (!current_override && isapnp_present()) {
 		struct pnp_dev *dev = NULL;
@@ -323,13 +353,21 @@ static int __init generic_NCR5380_detect(struct scsi_host_template *tpnt)
 			flags = FLAG_NO_PSEUDO_DMA;
 #endif
 			break;
+		case BOARD_HP53C400A:
+			flags = FLAG_NO_DMA_FIXUP;
+			ports = ncr_53c400a_ports;
+			magic = hp_53c400a_magic;
+			overrides[current_override].board = BOARD_NCR53C400A;
+			break;
 		case BOARD_NCR53C400A:
 			flags = FLAG_NO_DMA_FIXUP;
 			ports = ncr_53c400a_ports;
+			magic = ncr_53c400a_magic;
 			break;
 		case BOARD_DTC3181E:
 			flags = FLAG_NO_DMA_FIXUP;
 			ports = dtc_3181e_ports;
+			magic = ncr_53c400a_magic;
 			break;
 		}
 
@@ -338,12 +376,7 @@ static int __init generic_NCR5380_detect(struct scsi_host_template *tpnt)
 			/* wakeup sequence for the NCR53C400A and DTC3181E */
 
 			/* Disable the adapter and look for a free io port */
-			outb(0x59, 0x779);
-			outb(0xb9, 0x379);
-			outb(0xc5, 0x379);
-			outb(0xae, 0x379);
-			outb(0xa6, 0x379);
-			outb(0x00, 0x379);
+			magic_configure(-1, 0, magic);
 
 			if (overrides[current_override].NCR5380_map_name != PORT_AUTO)
 				for (i = 0; ports[i]; i++) {
@@ -362,17 +395,14 @@ static int __init generic_NCR5380_detect(struct scsi_host_template *tpnt)
 				}
 			if (ports[i]) {
 				/* At this point we have our region reserved */
-				outb(0x59, 0x779);
-				outb(0xb9, 0x379);
-				outb(0xc5, 0x379);
-				outb(0xae, 0x379);
-				outb(0xa6, 0x379);
-				outb(0x80 | i, 0x379);	/* set io port to be used */
+				magic_configure(i, 0, magic); /* no IRQ yet */
 				outb(0xc0, ports[i] + 9);
-				if (inb(ports[i] + 9) != 0x80)
+				if (inb(ports[i] + 9) != 0x80) {
 					continue;
-				else
+				} else {
 					overrides[current_override].NCR5380_map_name = ports[i];
+					port_idx = i;
+				}
 			} else
 				continue;
 		}
@@ -464,12 +494,18 @@ static int __init generic_NCR5380_detect(struct scsi_host_template *tpnt)
 		if (instance->irq == 255)
 			instance->irq = NO_IRQ;
 
-		if (instance->irq != NO_IRQ)
+		if (instance->irq != NO_IRQ) {
+#ifndef SCSI_G_NCR5380_MEM
+			/* set IRQ for HP 53C400A */
+			if (magic == hp_53c400a_magic)
+				magic_configure(port_idx, instance->irq, magic);
+#endif
 			if (request_irq(instance->irq, generic_NCR5380_intr,
 					0, "NCR5380", instance)) {
 				printk(KERN_WARNING "scsi%d : IRQ%d not free, interrupts disabled\n", instance->host_no, instance->irq);
 				instance->irq = NO_IRQ;
 			}
+		}
 
 		if (instance->irq == NO_IRQ) {
 			printk(KERN_INFO "scsi%d : interrupts not enabled. for better interactive performance,\n", instance->host_no);
@@ -763,6 +799,7 @@ module_param(ncr_5380, int, 0);
 module_param(ncr_53c400, int, 0);
 module_param(ncr_53c400a, int, 0);
 module_param(dtc_3181e, int, 0);
+module_param(hp_53c400a, int, 0);
 MODULE_LICENSE("GPL");
 
 #if !defined(SCSI_G_NCR5380_MEM) && defined(MODULE)
diff --git a/drivers/scsi/g_NCR5380.h b/drivers/scsi/g_NCR5380.h
index b3936aa..369ab9e 100644
--- a/drivers/scsi/g_NCR5380.h
+++ b/drivers/scsi/g_NCR5380.h
@@ -89,6 +89,7 @@
 #define BOARD_NCR53C400	1
 #define BOARD_NCR53C400A 2
 #define BOARD_DTC3181E	3
+#define BOARD_HP53C400A 4
 
 #endif /* GENERIC_NCR5380_H */
 
-- 
Ondrej Zary


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

* Re: [RFC PATCH 74/71] ncr5380: Enable PDMA for NCR53C400A
  2015-11-30 13:40     ` Ondrej Zary
@ 2015-12-06  3:20       ` Finn Thain
  0 siblings, 0 replies; 268+ messages in thread
From: Finn Thain @ 2015-12-06  3:20 UTC (permalink / raw)
  To: Ondrej Zary; +Cc: Michael Schmitz, linux-m68k, linux-scsi, linux-kernel


On Mon, 30 Nov 2015, Ondrej Zary wrote:

> On Monday 30 November 2015, Finn Thain wrote:
> > 
> > On Sun, 29 Nov 2015, Ondrej Zary wrote:
> > 
> > > Add I/O register mapping for NCR53C400A and enable PDMA mode to
> > > improve performance and fix non-working IRQ.
> > > 
> > 
> > Is CONFIG_SCSI_GENERIC_NCR53C400 is still needed? Can the driver be fully 
> > configured at runtime now?
> 
> Things depending on CONFIG_SCSI_GENERIC_NCR53C400:
> 
> #ifdef CONFIG_SCSI_GENERIC_NCR53C400
> #define PSEUDO_DMA
> #endif
> 
> Defining PSEUDO_DMA should not break anything, just makes code bigger a 
> bit. We can probably just define it always in g_NCR5380.c.

Based on your test results, I think so.

> 
> 
> This looks weird. I don't have any card with a BIOS to test.
> #ifdef CONFIG_SCSI_GENERIC_NCR53C400
> #define BIOSPARAM
> #define NCR5380_BIOSPARAM generic_NCR5380_biosparam
> #else
> #define NCR5380_BIOSPARAM NULL
> #endif
> 

I'm guessing that when you said "weird", you meant that it is weird to tie 
BIOSPARAM to CONFIG_SCSI_GENERIC_NCR53C400, because a 53C400-compatible 
device does not imply a card ROM, and generic_NCR5380_biosparam() does not 
require any particular device...

Regardless, the Kconfig help text doesn't say anything about bios_param, 
so I think that the weirdness you referred to should not prevent removal 
of CONFIG_SCSI_GENERIC_NCR53C400. I'm happy to let users manually #define 
BIOSPARAM if the default scsicam_bios_param() doesn't work. See patch 
below for example.

But if scsicam_bios_param() is adequate, or if generic_NCR5380_biosparam() 
is inadequate, then we should also remove generic_NCR5380_biosparam(), 
NCR5380_BIOSPARAM and BIOSPARAM. I'm not sufficiently familiar with this 
platform to say one way or the other.

> 
> This looks very wrong and should be done at runtime:
> #ifdef CONFIG_SCSI_GENERIC_NCR53C400
> #define NCR5380_region_size 16
> #else
> #define NCR5380_region_size 8
> #endif
> 

I'll have to leave that fix to you.

Thanks.


Index: linux/drivers/scsi/Kconfig
===================================================================
--- linux.orig/drivers/scsi/Kconfig	2015-12-06 12:29:36.000000000 +1100
+++ linux/drivers/scsi/Kconfig	2015-12-06 13:47:50.000000000 +1100
@@ -816,17 +816,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	2015-12-06 12:31:23.000000000 +1100
+++ linux/drivers/scsi/g_NCR5380.c	2015-12-06 13:45:42.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>
@@ -506,6 +503,9 @@ generic_NCR5380_biosparam(struct scsi_de
 	ip[2] = capacity >> 11;
 	return 0;
 }
+#define NCR5380_BIOSPARAM generic_NCR5380_biosparam
+#else
+#define NCR5380_BIOSPARAM NULL
 #endif
 
 #ifdef PSEUDO_DMA
Index: linux/drivers/scsi/g_NCR5380.h
===================================================================
--- linux.orig/drivers/scsi/g_NCR5380.h	2015-12-06 12:30:42.000000000 +1100
+++ linux/drivers/scsi/g_NCR5380.h	2015-12-06 13:47:12.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)
 
@@ -31,11 +24,9 @@
 #define NCR5380_map_name port
 #define NCR53C400_register_offset 0
 
-#ifdef CONFIG_SCSI_GENERIC_NCR53C400
-#define NCR5380_region_size 16
-#else
-#define NCR5380_region_size 8
-#endif
+// FIXME
+// #define NCR5380_region_size 16
+// #define NCR5380_region_size 8
 
 #define NCR5380_read(reg) \
 	inb(instance->io_port + (reg))

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

* Re: [RFC PATCH 78/71] ncr5380: Add support for HP 53C400A-based cards (C2502)
  2015-12-05 21:18 ` [RFC PATCH 78/71] ncr5380: Add support for HP 53C400A-based cards (C2502) Ondrej Zary
@ 2015-12-06  3:39   ` Finn Thain
  0 siblings, 0 replies; 268+ messages in thread
From: Finn Thain @ 2015-12-06  3:39 UTC (permalink / raw)
  To: Ondrej Zary; +Cc: Michael Schmitz, linux-m68k, linux-scsi, linux-kernel


On Sat, 5 Dec 2015, Ondrej Zary wrote:

> HP C2502 cards (based on 53C400A chips) use different magic numbers for 
> software-based I/O address configuration than other cards. The 
> configuration is also extended to allow setting the IRQ.
> 
> Move the configuration to a new function magic_configure() and move 
> magic the magic numbers into an array. Add new magic numbers for these 
> HP cards and hp_53c400a module parameter to use them.
> 
> Tested with HP C2502 and DTCT-436P.
> 
> Signed-off-by: Ondrej Zary <linux@rainbow-software.org>
> ---
>  drivers/scsi/g_NCR5380.c |   69 +++++++++++++++++++++++++++++++++++-----------
>  drivers/scsi/g_NCR5380.h |    1 +
>  2 files changed, 54 insertions(+), 16 deletions(-)
> 
> diff --git a/drivers/scsi/g_NCR5380.c b/drivers/scsi/g_NCR5380.c
> index 38579b0..52110e0 100644
> --- a/drivers/scsi/g_NCR5380.c
> +++ b/drivers/scsi/g_NCR5380.c
> @@ -80,6 +80,7 @@ static int ncr_5380;
>  static int ncr_53c400;
>  static int ncr_53c400a;
>  static int dtc_3181e;
> +static int hp_53c400a;
>  
>  static struct override {
>  	NCR5380_map_type NCR5380_map_name;
> @@ -225,6 +226,26 @@ static int __init do_DTC3181E_setup(char *str)
>  
>  #endif
>  
> +#ifndef SCSI_G_NCR5380_MEM
> +static void magic_configure(int idx, u8 irq, u8 magic[])
> +{
> +	u8 cfg = 0;
> +
> +	outb(magic[0], 0x779);
> +	outb(magic[1], 0x379);
> +	outb(magic[2], 0x379);
> +	outb(magic[3], 0x379);
> +	outb(magic[4], 0x379);
> +
> +	/* allowed IRQs for HP 53C400A */
> +	if (irq != 2 && irq != 3 && irq != 4 && irq != 5 && irq != 7)
> +		irq = 0;
> +	if (idx >= 0 && idx <= 7)
> +		cfg = 0x80 | idx | (irq << 4);
> +	outb(cfg, 0x379);
> +}
> +#endif
> +
>  /**
>   * 	generic_NCR5380_detect	-	look for NCR5380 controllers
>   *	@tpnt: the scsi template
> @@ -241,8 +262,9 @@ static int __init generic_NCR5380_detect(struct scsi_host_template *tpnt)
>  	static int current_override;
>  	int count;
>  	unsigned int *ports;
> +	u8 *magic;
>  #ifndef SCSI_G_NCR5380_MEM
> -	int i;
> +	int i, port_idx;
>  	unsigned long region_size = 16;
>  #endif
>  	static unsigned int __initdata ncr_53c400a_ports[] = {
> @@ -251,6 +273,12 @@ static int __init generic_NCR5380_detect(struct scsi_host_template *tpnt)
>  	static unsigned int __initdata dtc_3181e_ports[] = {
>  		0x220, 0x240, 0x280, 0x2a0, 0x2c0, 0x300, 0x320, 0x340, 0
>  	};
> +	static u8 ncr_53c400a_magic[] __initdata = {
> +		0x59, 0xb9, 0xc5, 0xae, 0xa6
> +	};
> +	static u8 hp_53c400a_magic[] __initdata = {
> +		0x0f, 0x22, 0xf0, 0x20, 0x80
> +	};

Magic numbers that are clearly labeled as such tells me that no-one can 
say what they actually mean... is that right?

>  	int flags;
>  	struct Scsi_Host *instance;
>  	struct NCR5380_hostdata *hostdata;
> @@ -273,6 +301,8 @@ static int __init generic_NCR5380_detect(struct scsi_host_template *tpnt)
>  		overrides[0].board = BOARD_NCR53C400A;
>  	else if (dtc_3181e)
>  		overrides[0].board = BOARD_DTC3181E;
> +	else if (hp_53c400a)
> +		overrides[0].board = BOARD_HP53C400A;
>  #ifndef SCSI_G_NCR5380_MEM
>  	if (!current_override && isapnp_present()) {
>  		struct pnp_dev *dev = NULL;
> @@ -323,13 +353,21 @@ static int __init generic_NCR5380_detect(struct scsi_host_template *tpnt)
>  			flags = FLAG_NO_PSEUDO_DMA;
>  #endif
>  			break;
> +		case BOARD_HP53C400A:
> +			flags = FLAG_NO_DMA_FIXUP;
> +			ports = ncr_53c400a_ports;
> +			magic = hp_53c400a_magic;

Nice! A new board.

> +			overrides[current_override].board = BOARD_NCR53C400A;

Do you rewrite overrides[current_override].board in order to avoid another 
term in a long conditional expression? Don't you find that confusing? Why 
not consistently use switch statements when we have to test 
overrides[current_override].board?

> +			break;
>  		case BOARD_NCR53C400A:
>  			flags = FLAG_NO_DMA_FIXUP;
>  			ports = ncr_53c400a_ports;
> +			magic = ncr_53c400a_magic;
>  			break;
>  		case BOARD_DTC3181E:
>  			flags = FLAG_NO_DMA_FIXUP;
>  			ports = dtc_3181e_ports;
> +			magic = ncr_53c400a_magic;
>  			break;
>  		}
>  
> @@ -338,12 +376,7 @@ static int __init generic_NCR5380_detect(struct scsi_host_template *tpnt)
>  			/* wakeup sequence for the NCR53C400A and DTC3181E */
>  
>  			/* Disable the adapter and look for a free io port */
> -			outb(0x59, 0x779);
> -			outb(0xb9, 0x379);
> -			outb(0xc5, 0x379);
> -			outb(0xae, 0x379);
> -			outb(0xa6, 0x379);
> -			outb(0x00, 0x379);
> +			magic_configure(-1, 0, magic);
>  
>  			if (overrides[current_override].NCR5380_map_name != PORT_AUTO)
>  				for (i = 0; ports[i]; i++) {
> @@ -362,17 +395,14 @@ static int __init generic_NCR5380_detect(struct scsi_host_template *tpnt)
>  				}
>  			if (ports[i]) {
>  				/* At this point we have our region reserved */
> -				outb(0x59, 0x779);
> -				outb(0xb9, 0x379);
> -				outb(0xc5, 0x379);
> -				outb(0xae, 0x379);
> -				outb(0xa6, 0x379);
> -				outb(0x80 | i, 0x379);	/* set io port to be used */
> +				magic_configure(i, 0, magic); /* no IRQ yet */
>  				outb(0xc0, ports[i] + 9);
> -				if (inb(ports[i] + 9) != 0x80)
> +				if (inb(ports[i] + 9) != 0x80) {
>  					continue;
> -				else
> +				} else {
>  					overrides[current_override].NCR5380_map_name = ports[i];
> +					port_idx = i;
> +				}
>  			} else
>  				continue;
>  		}
> @@ -464,12 +494,18 @@ static int __init generic_NCR5380_detect(struct scsi_host_template *tpnt)
>  		if (instance->irq == 255)
>  			instance->irq = NO_IRQ;
>  
> -		if (instance->irq != NO_IRQ)
> +		if (instance->irq != NO_IRQ) {
> +#ifndef SCSI_G_NCR5380_MEM
> +			/* set IRQ for HP 53C400A */
> +			if (magic == hp_53c400a_magic)
> +				magic_configure(port_idx, instance->irq, magic);
> +#endif

This would be better done earlier. We need to determine and assign the 
instance->irq value before NCR5380_init() in order to fix the irq number 
printed in the log messages when the driver starts. But that should 
probably be a separate patch...

>  			if (request_irq(instance->irq, generic_NCR5380_intr,
>  					0, "NCR5380", instance)) {
>  				printk(KERN_WARNING "scsi%d : IRQ%d not free, interrupts disabled\n", instance->host_no, instance->irq);
>  				instance->irq = NO_IRQ;
>  			}
> +		}
>  
>  		if (instance->irq == NO_IRQ) {
>  			printk(KERN_INFO "scsi%d : interrupts not enabled. for better interactive performance,\n", instance->host_no);
> @@ -763,6 +799,7 @@ module_param(ncr_5380, int, 0);
>  module_param(ncr_53c400, int, 0);
>  module_param(ncr_53c400a, int, 0);
>  module_param(dtc_3181e, int, 0);
> +module_param(hp_53c400a, int, 0);
>  MODULE_LICENSE("GPL");
>  
>  #if !defined(SCSI_G_NCR5380_MEM) && defined(MODULE)
> diff --git a/drivers/scsi/g_NCR5380.h b/drivers/scsi/g_NCR5380.h
> index b3936aa..369ab9e 100644
> --- a/drivers/scsi/g_NCR5380.h
> +++ b/drivers/scsi/g_NCR5380.h
> @@ -89,6 +89,7 @@
>  #define BOARD_NCR53C400	1
>  #define BOARD_NCR53C400A 2
>  #define BOARD_DTC3181E	3
> +#define BOARD_HP53C400A 4
>  
>  #endif /* GENERIC_NCR5380_H */
>  
> 

-- 

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

* Re: [PATCH 73/71] ncr5380: Use runtime register mapping
  2015-12-04 21:00 ` [PATCH 73/71] ncr5380: Use runtime register mapping Ondrej Zary
@ 2015-12-06  3:39   ` Finn Thain
  2015-12-06  8:42     ` Geert Uytterhoeven
  0 siblings, 1 reply; 268+ messages in thread
From: Finn Thain @ 2015-12-06  3:39 UTC (permalink / raw)
  To: Ondrej Zary; +Cc: Michael Schmitz, linux-m68k, linux-scsi, linux-kernel


On Fri, 4 Dec 2015, Ondrej Zary wrote:

> Convert compile-time C400_ register mapping to runtime mapping.
> This removes the weird negative register offsets and allows adding
> additional mappings.
> 
> Signed-off-by: Ondrej Zary <linux@rainbow-software.org>
> ---
>  drivers/scsi/NCR5380.h   |   13 +---------
>  drivers/scsi/g_NCR5380.c |   61 ++++++++++++++++++++++++++--------------------
>  drivers/scsi/g_NCR5380.h |   12 ++++++---
>  3 files changed, 43 insertions(+), 43 deletions(-)
> 
> diff --git a/drivers/scsi/NCR5380.h b/drivers/scsi/NCR5380.h
> index 36779df..923db6c 100644
> --- a/drivers/scsi/NCR5380.h
> +++ b/drivers/scsi/NCR5380.h
> @@ -163,8 +163,7 @@
>  /* Write any value to this register to start an ini mode DMA receive */
>  #define START_DMA_INITIATOR_RECEIVE_REG 7	/* wo */
>  
> -#define C400_CONTROL_STATUS_REG NCR53C400_register_offset-8	/* rw */
> -
> +/* NCR 53C400(A) Control Status Register bits: */
>  #define CSR_RESET              0x80	/* wo  Resets 53c400 */
>  #define CSR_53C80_REG          0x80	/* ro  5380 registers busy */
>  #define CSR_TRANS_DIR          0x40	/* rw  Data transfer direction */
> @@ -181,16 +180,6 @@
>  #define CSR_BASE CSR_53C80_INTR
>  #endif
>  
> -/* Number of 128-byte blocks to be transferred */
> -#define C400_BLOCK_COUNTER_REG   NCR53C400_register_offset-7	/* rw */
> -
> -/* Resume transfer after disconnect */
> -#define C400_RESUME_TRANSFER_REG NCR53C400_register_offset-6	/* wo */
> -
> -/* Access to host buffer stack */
> -#define C400_HOST_BUFFER         NCR53C400_register_offset-4	/* rw */
> -
> -
>  /* Note : PHASE_* macros are based on the values of the STATUS register */
>  #define PHASE_MASK 	(SR_MSG | SR_CD | SR_IO)
>  
> diff --git a/drivers/scsi/g_NCR5380.c b/drivers/scsi/g_NCR5380.c
> index a9a237f..ce444da 100644
> --- a/drivers/scsi/g_NCR5380.c
> +++ b/drivers/scsi/g_NCR5380.c
> @@ -253,6 +253,7 @@ static int __init generic_NCR5380_detect(struct scsi_host_template *tpnt)
>  	};
>  	int flags;
>  	struct Scsi_Host *instance;
> +	struct NCR5380_hostdata *hostdata;
>  #ifdef SCSI_G_NCR5380_MEM
>  	unsigned long base;
>  	void __iomem *iomem;
> @@ -395,6 +396,7 @@ static int __init generic_NCR5380_detect(struct scsi_host_template *tpnt)
>  		instance = scsi_register(tpnt, sizeof(struct NCR5380_hostdata));
>  		if (instance == NULL)
>  			goto out_release;
> +		hostdata = shost_priv(instance);
>  
>  #ifndef SCSI_G_NCR5380_MEM
>  		instance->io_port = overrides[current_override].NCR5380_map_name;
> @@ -404,18 +406,27 @@ static int __init generic_NCR5380_detect(struct scsi_host_template *tpnt)
>  		 * On NCR53C400 boards, NCR5380 registers are mapped 8 past
>  		 * the base address.
>  		 */
> -		if (overrides[current_override].board == BOARD_NCR53C400)
> +		if (overrides[current_override].board == BOARD_NCR53C400) {
>  			instance->io_port += 8;
> +			hostdata->c400_ctl_status = 0;
> +			hostdata->c400_blk_cnt = 1;
> +			hostdata->c400_host_buf = 4;
> +		}
>  #else
>  		instance->base = overrides[current_override].NCR5380_map_name;
> -		((struct NCR5380_hostdata *)instance->hostdata)->iomem = iomem;
> +		hostdata->iomem = iomem;
> +		if (overrides[current_override].board == BOARD_NCR53C400) {
> +			hostdata->c400_ctl_status = 0x100;
> +			hostdata->c400_blk_cnt = 0x101;
> +			hostdata->c400_host_buf = 0x104;
> +		}
>  #endif
>  
>  		if (NCR5380_init(instance, flags))
>  			goto out_unregister;
>  
>  		if (overrides[current_override].board == BOARD_NCR53C400)
> -			NCR5380_write(C400_CONTROL_STATUS_REG, CSR_BASE);
> +			NCR5380_write(hostdata->c400_ctl_status, CSR_BASE);
>  
>  		NCR5380_maybe_reset_bus(instance);
>  
> @@ -523,30 +534,28 @@ generic_NCR5380_biosparam(struct scsi_device *sdev, struct block_device *bdev,
>   
>  static inline int NCR5380_pread(struct Scsi_Host *instance, unsigned char *dst, int len)
>  {
> -#ifdef SCSI_G_NCR5380_MEM
>  	struct NCR5380_hostdata *hostdata = shost_priv(instance);
> -#endif
>  	int blocks = len / 128;
>  	int start = 0;
>  	int bl;
>  
> -	NCR5380_write(C400_CONTROL_STATUS_REG, CSR_BASE | CSR_TRANS_DIR);
> -	NCR5380_write(C400_BLOCK_COUNTER_REG, blocks);
> +	NCR5380_write(hostdata->c400_ctl_status, CSR_BASE | CSR_TRANS_DIR);
> +	NCR5380_write(hostdata->c400_blk_cnt, blocks);
>  	while (1) {
> -		if ((bl = NCR5380_read(C400_BLOCK_COUNTER_REG)) == 0) {
> +		if ((bl = NCR5380_read(hostdata->c400_blk_cnt)) == 0) {
>  			break;
>  		}

Rewritten in Linux coding style that is,

	bl = NCR5380_read(hostdata->c400_blk_cnt);
	if (bl == 0)
		break;

But in this case, bl is not used further so why not just remove it along 
with the braces?

> -		if (NCR5380_read(C400_CONTROL_STATUS_REG) & CSR_GATED_53C80_IRQ) {
> +		if (NCR5380_read(hostdata->c400_ctl_status) & CSR_GATED_53C80_IRQ) {
>  			printk(KERN_ERR "53C400r: Got 53C80_IRQ start=%d, blocks=%d\n", start, blocks);
>  			return -1;
>  		}
> -		while (NCR5380_read(C400_CONTROL_STATUS_REG) & CSR_HOST_BUF_NOT_RDY);
> +		while (NCR5380_read(hostdata->c400_ctl_status) & CSR_HOST_BUF_NOT_RDY);

The semicolon should appear on the next line where it is more visible.

>  
>  #ifndef SCSI_G_NCR5380_MEM
>  		{
>  			int i;
>  			for (i = 0; i < 128; i++)
> -				dst[start + i] = NCR5380_read(C400_HOST_BUFFER);
> +				dst[start + i] = NCR5380_read(hostdata->c400_host_buf);
>  		}

Why not just change the loop to insb() now, rather than waiting until the 
patch after next? Then you can remove the extra braces and 'int i' 
declaration.

>  #else
>  		/* implies SCSI_G_NCR5380_MEM */
> @@ -558,7 +567,7 @@ static inline int NCR5380_pread(struct Scsi_Host *instance, unsigned char *dst,
>  	}
>  
>  	if (blocks) {
> -		while (NCR5380_read(C400_CONTROL_STATUS_REG) & CSR_HOST_BUF_NOT_RDY)
> +		while (NCR5380_read(hostdata->c400_ctl_status) & CSR_HOST_BUF_NOT_RDY)
>  		{
>  			// FIXME - no timeout
>  		}
> @@ -567,7 +576,7 @@ static inline int NCR5380_pread(struct Scsi_Host *instance, unsigned char *dst,
>  		{
>  			int i;	
>  			for (i = 0; i < 128; i++)
> -				dst[start + i] = NCR5380_read(C400_HOST_BUFFER);
> +				dst[start + i] = NCR5380_read(hostdata->c400_host_buf);

Same here.

>  		}
>  #else
>  		/* implies SCSI_G_NCR5380_MEM */
> @@ -578,7 +587,7 @@ static inline int NCR5380_pread(struct Scsi_Host *instance, unsigned char *dst,
>  		blocks--;
>  	}
>  
> -	if (!(NCR5380_read(C400_CONTROL_STATUS_REG) & CSR_GATED_53C80_IRQ))
> +	if (!(NCR5380_read(hostdata->c400_ctl_status) & CSR_GATED_53C80_IRQ))
>  		printk("53C400r: no 53C80 gated irq after transfer");
>  
>  #if 0
> @@ -586,7 +595,7 @@ static inline int NCR5380_pread(struct Scsi_Host *instance, unsigned char *dst,
>  	 *	DON'T DO THIS - THEY NEVER ARRIVE!
>  	 */
>  	printk("53C400r: Waiting for 53C80 registers\n");
> -	while (NCR5380_read(C400_CONTROL_STATUS_REG) & CSR_53C80_REG)
> +	while (NCR5380_read(hostdata->c400_ctl_status) & CSR_53C80_REG)
>  		;
>  #endif
>  	if (!(NCR5380_read(BUS_AND_STATUS_REG) & BASR_END_DMA_TRANSFER))
> @@ -607,31 +616,29 @@ static inline int NCR5380_pread(struct Scsi_Host *instance, unsigned char *dst,
>  
>  static inline int NCR5380_pwrite(struct Scsi_Host *instance, unsigned char *src, int len)
>  {
> -#ifdef SCSI_G_NCR5380_MEM
>  	struct NCR5380_hostdata *hostdata = shost_priv(instance);
> -#endif
>  	int blocks = len / 128;
>  	int start = 0;
>  	int bl;
>  	int i;
>  
> -	NCR5380_write(C400_CONTROL_STATUS_REG, CSR_BASE);
> -	NCR5380_write(C400_BLOCK_COUNTER_REG, blocks);
> +	NCR5380_write(hostdata->c400_ctl_status, CSR_BASE);
> +	NCR5380_write(hostdata->c400_blk_cnt, blocks);
>  	while (1) {
> -		if (NCR5380_read(C400_CONTROL_STATUS_REG) & CSR_GATED_53C80_IRQ) {
> +		if (NCR5380_read(hostdata->c400_ctl_status) & CSR_GATED_53C80_IRQ) {
>  			printk(KERN_ERR "53C400w: Got 53C80_IRQ start=%d, blocks=%d\n", start, blocks);
>  			return -1;
>  		}
>  
> -		if ((bl = NCR5380_read(C400_BLOCK_COUNTER_REG)) == 0) {
> +		if ((bl = NCR5380_read(hostdata->c400_blk_cnt)) == 0) {

As above.

>  			break;
>  		}
> -		while (NCR5380_read(C400_CONTROL_STATUS_REG) & CSR_HOST_BUF_NOT_RDY)
> +		while (NCR5380_read(hostdata->c400_ctl_status) & CSR_HOST_BUF_NOT_RDY)
>  			; // FIXME - timeout
>  #ifndef SCSI_G_NCR5380_MEM
>  		{
>  			for (i = 0; i < 128; i++)
> -				NCR5380_write(C400_HOST_BUFFER, src[start + i]);
> +				NCR5380_write(hostdata->c400_host_buf, src[start + i]);
>  		}

Also as above.

>  #else
>  		/* implies SCSI_G_NCR5380_MEM */
> @@ -642,13 +649,13 @@ static inline int NCR5380_pwrite(struct Scsi_Host *instance, unsigned char *src,
>  		blocks--;
>  	}
>  	if (blocks) {
> -		while (NCR5380_read(C400_CONTROL_STATUS_REG) & CSR_HOST_BUF_NOT_RDY)
> +		while (NCR5380_read(hostdata->c400_ctl_status) & CSR_HOST_BUF_NOT_RDY)
>  			; // FIXME - no timeout
>  
>  #ifndef SCSI_G_NCR5380_MEM
>  		{
>  			for (i = 0; i < 128; i++)
> -				NCR5380_write(C400_HOST_BUFFER, src[start + i]);
> +				NCR5380_write(hostdata->c400_host_buf, src[start + i]);
>  		}

Same here.

Thanks.

>  #else
>  		/* implies SCSI_G_NCR5380_MEM */
> @@ -661,7 +668,7 @@ static inline int NCR5380_pwrite(struct Scsi_Host *instance, unsigned char *src,
>  
>  #if 0
>  	printk("53C400w: waiting for registers to be available\n");
> -	THEY NEVER DO ! while (NCR5380_read(C400_CONTROL_STATUS_REG) & CSR_53C80_REG);
> +	THEY NEVER DO ! while (NCR5380_read(hostdata->c400_ctl_status) & CSR_53C80_REG);
>  	printk("53C400w: Got em\n");
>  #endif
>  
> @@ -669,7 +676,7 @@ static inline int NCR5380_pwrite(struct Scsi_Host *instance, unsigned char *src,
>  	/* All documentation says to check for this. Maybe my hardware is too
>  	 * fast. Waiting for it seems to work fine! KLL
>  	 */
> -	while (!(i = NCR5380_read(C400_CONTROL_STATUS_REG) & CSR_GATED_53C80_IRQ))
> +	while (!(i = NCR5380_read(hostdata->c400_ctl_status) & CSR_GATED_53C80_IRQ))
>  		;	// FIXME - no timeout
>  
>  	/*
> diff --git a/drivers/scsi/g_NCR5380.h b/drivers/scsi/g_NCR5380.h
> index fd201e9..c5e57b7 100644
> --- a/drivers/scsi/g_NCR5380.h
> +++ b/drivers/scsi/g_NCR5380.h
> @@ -29,7 +29,6 @@
>  
>  #define NCR5380_map_type int
>  #define NCR5380_map_name port
> -#define NCR53C400_register_offset 0
>  
>  #ifdef CONFIG_SCSI_GENERIC_NCR53C400
>  #define NCR5380_region_size 16
> @@ -42,7 +41,10 @@
>  #define NCR5380_write(reg, value) \
>  	outb(value, instance->io_port + (reg))
>  
> -#define NCR5380_implementation_fields /* none */
> +#define NCR5380_implementation_fields \
> +	int c400_ctl_status; \
> +	int c400_blk_cnt; \
> +	int c400_host_buf;
>  
>  #else 
>  /* therefore SCSI_G_NCR5380_MEM */
> @@ -50,7 +52,6 @@
>  
>  #define NCR5380_map_type unsigned long
>  #define NCR5380_map_name base
> -#define NCR53C400_register_offset 0x108
>  #define NCR53C400_mem_base 0x3880
>  #define NCR53C400_host_buffer 0x3900
>  #define NCR5380_region_size 0x3a00
> @@ -63,7 +64,10 @@
>  	       NCR53C400_mem_base + (reg))
>  
>  #define NCR5380_implementation_fields \
> -    void __iomem *iomem;
> +	void __iomem *iomem; \
> +	int c400_ctl_status; \
> +	int c400_blk_cnt; \
> +	int c400_host_buf;
>  
>  #endif
>  
> 

-- 

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

* Re: [PATCH 76/71] ncr5380: Enable PDMA for DTC chips
  2015-12-04 21:17 ` [PATCH 76/71] ncr5380: Enable PDMA for DTC chips Ondrej Zary
@ 2015-12-06  3:40   ` Finn Thain
  2015-12-06 22:47     ` Ondrej Zary
  0 siblings, 1 reply; 268+ messages in thread
From: Finn Thain @ 2015-12-06  3:40 UTC (permalink / raw)
  To: Ondrej Zary; +Cc: Michael Schmitz, linux-m68k, linux-scsi, linux-kernel


On Fri, 4 Dec 2015, Ondrej Zary wrote:

> Add I/O register mapping for DTC chips and enable PDMA mode.
> 
> These chips have 16-bit wide HOST BUFFER register (counter register at
> offset 0x0d increments by 2 on each HOST BUFFER read). Detect it
> automatically.
> 
> Large PIO transfers crash at least the DTCT-436P chip (all reads result
> in 0xFF) so this patch actually makes it work.
> 
> The chip also crashes when we bang the C400 host status register too
> heavily after PDMA write - a small udelay is needed.
> 
> Tested on DTCT-436P and verified that it does not break 53C400A.
> 
> Signed-off-by: Ondrej Zary <linux@rainbow-software.org>
> ---
>  drivers/scsi/g_NCR5380.c |   59 ++++++++++++++++++++++++++++------------------
>  drivers/scsi/g_NCR5380.h |    4 +++-
>  2 files changed, 39 insertions(+), 24 deletions(-)
> 
> diff --git a/drivers/scsi/g_NCR5380.c b/drivers/scsi/g_NCR5380.c
> index 85da3c2..9816b81 100644
> --- a/drivers/scsi/g_NCR5380.c
> +++ b/drivers/scsi/g_NCR5380.c
> @@ -328,7 +328,7 @@ static int __init generic_NCR5380_detect(struct scsi_host_template *tpnt)
>  			ports = ncr_53c400a_ports;
>  			break;
>  		case BOARD_DTC3181E:
> -			flags = FLAG_NO_PSEUDO_DMA;
> +			flags = FLAG_NO_DMA_FIXUP;

Nice!

>  			ports = dtc_3181e_ports;
>  			break;
>  		}
> @@ -412,10 +412,12 @@ static int __init generic_NCR5380_detect(struct scsi_host_template *tpnt)
>  			hostdata->c400_blk_cnt = 1;
>  			hostdata->c400_host_buf = 4;
>  		}
> -		if (overrides[current_override].board == BOARD_NCR53C400A) {
> +		if (overrides[current_override].board == BOARD_NCR53C400A ||
> +		    overrides[current_override].board == BOARD_DTC3181E) {
>  			hostdata->c400_ctl_status = 9;
>  			hostdata->c400_blk_cnt = 10;
>  			hostdata->c400_host_buf = 8;
> +			hostdata->c400_host_idx = 13;
>  		}
>  #else
>  		instance->base = overrides[current_override].NCR5380_map_name;
> @@ -430,8 +432,20 @@ static int __init generic_NCR5380_detect(struct scsi_host_template *tpnt)
>  		if (NCR5380_init(instance, flags))
>  			goto out_unregister;
>  
> +#ifndef SCSI_G_NCR5380_MEM
> +		/* read initial value of index register */
> +		i = NCR5380_read(hostdata->c400_host_idx);
> +		/* read something from host buffer */
> +		NCR5380_read(hostdata->c400_host_buf);
> +		/* I/O width = index register increment */
> +		hostdata->io_width = NCR5380_read(hostdata->c400_host_idx) - i;
> +		if (hostdata->io_width < 0)
> +			hostdata->io_width += 128;
> +#endif

Will the result depend on the initial state of the chip, such as
CSR_TRANS_DIR or CSR_HOST_BUF_NOT_RDY?

It is possible to generate an interrupt with the buffer read, which should 
be masked at the chip.

This buffer read may cause the 53C400 control logic to signal the 53C80 
core. I suppose it is unlikely to cause any signalling on the SCSI bus 
unless the 53C80 happened to be in DMA mode.

The possibility that io_width == 0 is not handled; wouldn't this result 
indicate that PDMA shouldn't be used?

io_width can be calculated without a conditional statement, which may be 
easier to read.

Can we be confident that detection will fail for all devices that don't 
support word-sized IO, to avoid a regression?

The patch seems to assume that no memory-mapped card needs word-sized IO 
for PDMA. Can you confirm?

The previous version of this patch was simpler and more predictable. You 
enabled word-size IO for DTC3181E which is testable. Does this version 
benefit any other cards?

> +
>  		if (overrides[current_override].board == BOARD_NCR53C400 ||
> -		    overrides[current_override].board == BOARD_NCR53C400A)
> +		    overrides[current_override].board == BOARD_NCR53C400A ||
> +		    overrides[current_override].board == BOARD_DTC3181E)
>  			NCR5380_write(hostdata->c400_ctl_status, CSR_BASE);
>  
>  		NCR5380_maybe_reset_bus(instance);
> @@ -558,11 +572,10 @@ static inline int NCR5380_pread(struct Scsi_Host *instance, unsigned char *dst,
>  		while (NCR5380_read(hostdata->c400_ctl_status) & CSR_HOST_BUF_NOT_RDY);
>  
>  #ifndef SCSI_G_NCR5380_MEM
> -		{
> -			int i;
> -			for (i = 0; i < 128; i++)
> -				dst[start + i] = NCR5380_read(hostdata->c400_host_buf);
> -		}
> +		if (hostdata->io_width == 2)
> +			insw(instance->io_port + hostdata->c400_host_buf, dst + start, 64);
> +		else
> +			insb(instance->io_port + hostdata->c400_host_buf, dst + start, 128);
>  #else
>  		/* implies SCSI_G_NCR5380_MEM */
>  		memcpy_fromio(dst + start,
> @@ -579,11 +592,10 @@ static inline int NCR5380_pread(struct Scsi_Host *instance, unsigned char *dst,
>  		}
>  
>  #ifndef SCSI_G_NCR5380_MEM
> -		{
> -			int i;	
> -			for (i = 0; i < 128; i++)
> -				dst[start + i] = NCR5380_read(hostdata->c400_host_buf);
> -		}
> +		if (hostdata->io_width == 2)
> +			insw(instance->io_port + hostdata->c400_host_buf, dst + start, 64);
> +		else
> +			insb(instance->io_port + hostdata->c400_host_buf, dst + start, 128);
>  #else
>  		/* implies SCSI_G_NCR5380_MEM */
>  		memcpy_fromio(dst + start,
> @@ -642,10 +654,10 @@ static inline int NCR5380_pwrite(struct Scsi_Host *instance, unsigned char *src,
>  		while (NCR5380_read(hostdata->c400_ctl_status) & CSR_HOST_BUF_NOT_RDY)
>  			; // FIXME - timeout
>  #ifndef SCSI_G_NCR5380_MEM
> -		{
> -			for (i = 0; i < 128; i++)
> -				NCR5380_write(hostdata->c400_host_buf, src[start + i]);
> -		}
> +		if (hostdata->io_width == 2)
> +			outsw(instance->io_port + hostdata->c400_host_buf, src + start, 64);
> +		else
> +			outsb(instance->io_port + hostdata->c400_host_buf, src + start, 128);
>  #else
>  		/* implies SCSI_G_NCR5380_MEM */
>  		memcpy_toio(hostdata->iomem + NCR53C400_host_buffer,
> @@ -657,12 +669,11 @@ static inline int NCR5380_pwrite(struct Scsi_Host *instance, unsigned char *src,
>  	if (blocks) {
>  		while (NCR5380_read(hostdata->c400_ctl_status) & CSR_HOST_BUF_NOT_RDY)
>  			; // FIXME - no timeout
> -
>  #ifndef SCSI_G_NCR5380_MEM
> -		{
> -			for (i = 0; i < 128; i++)
> -				NCR5380_write(hostdata->c400_host_buf, src[start + i]);
> -		}
> +		if (hostdata->io_width == 2)
> +			outsw(instance->io_port + hostdata->c400_host_buf, src + start, 64);
> +		else
> +			outsb(instance->io_port + hostdata->c400_host_buf, src + start, 128);
>  #else
>  		/* implies SCSI_G_NCR5380_MEM */
>  		memcpy_toio(hostdata->iomem + NCR53C400_host_buffer,
> @@ -682,8 +693,10 @@ static inline int NCR5380_pwrite(struct Scsi_Host *instance, unsigned char *src,
>  	/* All documentation says to check for this. Maybe my hardware is too
>  	 * fast. Waiting for it seems to work fine! KLL
>  	 */
> -	while (!(i = NCR5380_read(hostdata->c400_ctl_status) & CSR_GATED_53C80_IRQ))
> +	while (!(i = NCR5380_read(hostdata->c400_ctl_status) & CSR_GATED_53C80_IRQ)) {
> +		udelay(4); /* DTC436 chip hangs without this */
>  		;	// FIXME - no timeout
> +	}

When you added the braces, the lone semicolon became redundant. But I 
think the entire loop is bogus.

Why do we wait for CSR_GATED_53C80_IRQ? I can understand testing it during 
a transfer but why afterwards? (The core driver could test for the IRQ 
flag in the Bus and Status Register, at the end of a DMA, if this scsi 
host has no IRQ line.)

The comments and the 53C400 datasheet say we should instead wait for 
CSR_53C80_REG. I agree. The g_NCR5380 wrapper driver can't safely return 
control to the core driver unless the 53C80 registers are available.

The algorithm in the datasheet waits for CSR_53C80_REG before checking 
BASR_END_DMA_TRANSFER, checking interrupt flags, disabling DMA mode etc. 

g_NCR5380.c has an '#if 0' around the BASR_END_DMA_TRANSFER check, because 
it doesn't wait for CSR_53C80_REG. Does NCR's algorithm work with your 
cards?

>  
>  	/*
>  	 * I know. i is certainly != 0 here but the loop is new. See previous
> diff --git a/drivers/scsi/g_NCR5380.h b/drivers/scsi/g_NCR5380.h
> index c5e57b7..b3936aa 100644
> --- a/drivers/scsi/g_NCR5380.h
> +++ b/drivers/scsi/g_NCR5380.h
> @@ -44,7 +44,9 @@
>  #define NCR5380_implementation_fields \
>  	int c400_ctl_status; \
>  	int c400_blk_cnt; \
> -	int c400_host_buf;
> +	int c400_host_buf; \
> +	int c400_host_idx; \
> +	int io_width;
>  
>  #else 
>  /* therefore SCSI_G_NCR5380_MEM */
> 

-- 

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

* Re: [PATCH 74/71] ncr5380: Enable PDMA for NCR53C400A
  2015-12-04 21:02 ` [PATCH 74/71] ncr5380: Enable PDMA for NCR53C400A Ondrej Zary
@ 2015-12-06  3:41   ` Finn Thain
  0 siblings, 0 replies; 268+ messages in thread
From: Finn Thain @ 2015-12-06  3:41 UTC (permalink / raw)
  To: Ondrej Zary; +Cc: Michael Schmitz, linux-m68k, linux-scsi, linux-kernel


On Fri, 4 Dec 2015, Ondrej Zary wrote:

> Add I/O register mapping for NCR53C400A and enable PDMA mode to
> improve performance and fix non-working IRQ.
> 
> Tested with HP C2502 (and user-space enabler).
> 
> Signed-off-by: Ondrej Zary <linux@rainbow-software.org>
> ---
>  drivers/scsi/g_NCR5380.c |   10 ++++++++--
>  1 file changed, 8 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/scsi/g_NCR5380.c b/drivers/scsi/g_NCR5380.c
> index ce444da..cd483c6 100644
> --- a/drivers/scsi/g_NCR5380.c
> +++ b/drivers/scsi/g_NCR5380.c
> @@ -324,7 +324,7 @@ static int __init generic_NCR5380_detect(struct scsi_host_template *tpnt)
>  #endif
>  			break;
>  		case BOARD_NCR53C400A:
> -			flags = FLAG_NO_PSEUDO_DMA;
> +			flags = FLAG_NO_DMA_FIXUP;

Nice!

>  			ports = ncr_53c400a_ports;
>  			break;
>  		case BOARD_DTC3181E:
> @@ -412,6 +412,11 @@ static int __init generic_NCR5380_detect(struct scsi_host_template *tpnt)
>  			hostdata->c400_blk_cnt = 1;
>  			hostdata->c400_host_buf = 4;
>  		}
> +		if (overrides[current_override].board == BOARD_NCR53C400A) {

Please use an 'else' here. Or a switch statement.

> +			hostdata->c400_ctl_status = 9;
> +			hostdata->c400_blk_cnt = 10;
> +			hostdata->c400_host_buf = 8;
> +		}
>  #else
>  		instance->base = overrides[current_override].NCR5380_map_name;
>  		hostdata->iomem = iomem;
> @@ -425,7 +430,8 @@ static int __init generic_NCR5380_detect(struct scsi_host_template *tpnt)
>  		if (NCR5380_init(instance, flags))
>  			goto out_unregister;
>  
> -		if (overrides[current_override].board == BOARD_NCR53C400)
> +		if (overrides[current_override].board == BOARD_NCR53C400 ||
> +		    overrides[current_override].board == BOARD_NCR53C400A)
>  			NCR5380_write(hostdata->c400_ctl_status, CSR_BASE);
>  
>  		NCR5380_maybe_reset_bus(instance);
> 

-- 

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

* Re: [PATCH 73/71] ncr5380: Use runtime register mapping
  2015-12-06  3:39   ` Finn Thain
@ 2015-12-06  8:42     ` Geert Uytterhoeven
  0 siblings, 0 replies; 268+ messages in thread
From: Geert Uytterhoeven @ 2015-12-06  8:42 UTC (permalink / raw)
  To: Finn Thain; +Cc: Ondrej Zary, Michael Schmitz, Linux/m68k, scsi, linux-kernel

On Sun, Dec 6, 2015 at 4:39 AM, Finn Thain <fthain@telegraphics.com.au> wrote:
>> -             while (NCR5380_read(C400_CONTROL_STATUS_REG) & CSR_HOST_BUF_NOT_RDY);
>> +             while (NCR5380_read(hostdata->c400_ctl_status) & CSR_HOST_BUF_NOT_RDY);
>
> The semicolon should appear on the next line where it is more visible.

And adding a cpu_relax() to the empty loop body is another good visual cue.

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] 268+ messages in thread

* [PATCH v2 73/71] ncr5380: Use runtime register mapping
  2015-11-18  8:34 ` Finn Thain
                   ` (82 preceding siblings ...)
  (?)
@ 2015-12-06 22:20 ` Ondrej Zary
  -1 siblings, 0 replies; 268+ messages in thread
From: Ondrej Zary @ 2015-12-06 22:20 UTC (permalink / raw)
  To: Finn Thain, Michael Schmitz, linux-m68k, linux-scsi, linux-kernel

Convert compile-time C400_ register mapping to runtime mapping.
This removes the weird negative register offsets and allows adding
additional mappings.

While at it, convert read/write loops into insb/outsb.

Signed-off-by: Ondrej Zary <linux@rainbow-software.org>
---
 drivers/scsi/NCR5380.h   |   13 +------
 drivers/scsi/g_NCR5380.c |   88 +++++++++++++++++++++-------------------------
 drivers/scsi/g_NCR5380.h |   12 ++++---
 3 files changed, 49 insertions(+), 64 deletions(-)

diff --git a/drivers/scsi/NCR5380.h b/drivers/scsi/NCR5380.h
index 36779df..923db6c 100644
--- a/drivers/scsi/NCR5380.h
+++ b/drivers/scsi/NCR5380.h
@@ -163,8 +163,7 @@
 /* Write any value to this register to start an ini mode DMA receive */
 #define START_DMA_INITIATOR_RECEIVE_REG 7	/* wo */
 
-#define C400_CONTROL_STATUS_REG NCR53C400_register_offset-8	/* rw */
-
+/* NCR 53C400(A) Control Status Register bits: */
 #define CSR_RESET              0x80	/* wo  Resets 53c400 */
 #define CSR_53C80_REG          0x80	/* ro  5380 registers busy */
 #define CSR_TRANS_DIR          0x40	/* rw  Data transfer direction */
@@ -181,16 +180,6 @@
 #define CSR_BASE CSR_53C80_INTR
 #endif
 
-/* Number of 128-byte blocks to be transferred */
-#define C400_BLOCK_COUNTER_REG   NCR53C400_register_offset-7	/* rw */
-
-/* Resume transfer after disconnect */
-#define C400_RESUME_TRANSFER_REG NCR53C400_register_offset-6	/* wo */
-
-/* Access to host buffer stack */
-#define C400_HOST_BUFFER         NCR53C400_register_offset-4	/* rw */
-
-
 /* Note : PHASE_* macros are based on the values of the STATUS register */
 #define PHASE_MASK 	(SR_MSG | SR_CD | SR_IO)
 
diff --git a/drivers/scsi/g_NCR5380.c b/drivers/scsi/g_NCR5380.c
index a9a237f..86740fd 100644
--- a/drivers/scsi/g_NCR5380.c
+++ b/drivers/scsi/g_NCR5380.c
@@ -253,6 +253,7 @@ static int __init generic_NCR5380_detect(struct scsi_host_template *tpnt)
 	};
 	int flags;
 	struct Scsi_Host *instance;
+	struct NCR5380_hostdata *hostdata;
 #ifdef SCSI_G_NCR5380_MEM
 	unsigned long base;
 	void __iomem *iomem;
@@ -395,6 +396,7 @@ static int __init generic_NCR5380_detect(struct scsi_host_template *tpnt)
 		instance = scsi_register(tpnt, sizeof(struct NCR5380_hostdata));
 		if (instance == NULL)
 			goto out_release;
+		hostdata = shost_priv(instance);
 
 #ifndef SCSI_G_NCR5380_MEM
 		instance->io_port = overrides[current_override].NCR5380_map_name;
@@ -404,18 +406,27 @@ static int __init generic_NCR5380_detect(struct scsi_host_template *tpnt)
 		 * On NCR53C400 boards, NCR5380 registers are mapped 8 past
 		 * the base address.
 		 */
-		if (overrides[current_override].board == BOARD_NCR53C400)
+		if (overrides[current_override].board == BOARD_NCR53C400) {
 			instance->io_port += 8;
+			hostdata->c400_ctl_status = 0;
+			hostdata->c400_blk_cnt = 1;
+			hostdata->c400_host_buf = 4;
+		}
 #else
 		instance->base = overrides[current_override].NCR5380_map_name;
-		((struct NCR5380_hostdata *)instance->hostdata)->iomem = iomem;
+		hostdata->iomem = iomem;
+		if (overrides[current_override].board == BOARD_NCR53C400) {
+			hostdata->c400_ctl_status = 0x100;
+			hostdata->c400_blk_cnt = 0x101;
+			hostdata->c400_host_buf = 0x104;
+		}
 #endif
 
 		if (NCR5380_init(instance, flags))
 			goto out_unregister;
 
 		if (overrides[current_override].board == BOARD_NCR53C400)
-			NCR5380_write(C400_CONTROL_STATUS_REG, CSR_BASE);
+			NCR5380_write(hostdata->c400_ctl_status, CSR_BASE);
 
 		NCR5380_maybe_reset_bus(instance);
 
@@ -523,31 +534,25 @@ generic_NCR5380_biosparam(struct scsi_device *sdev, struct block_device *bdev,
  
 static inline int NCR5380_pread(struct Scsi_Host *instance, unsigned char *dst, int len)
 {
-#ifdef SCSI_G_NCR5380_MEM
 	struct NCR5380_hostdata *hostdata = shost_priv(instance);
-#endif
 	int blocks = len / 128;
 	int start = 0;
-	int bl;
 
-	NCR5380_write(C400_CONTROL_STATUS_REG, CSR_BASE | CSR_TRANS_DIR);
-	NCR5380_write(C400_BLOCK_COUNTER_REG, blocks);
+	NCR5380_write(hostdata->c400_ctl_status, CSR_BASE | CSR_TRANS_DIR);
+	NCR5380_write(hostdata->c400_blk_cnt, blocks);
 	while (1) {
-		if ((bl = NCR5380_read(C400_BLOCK_COUNTER_REG)) == 0) {
+		if (NCR5380_read(hostdata->c400_blk_cnt) == 0)
 			break;
-		}
-		if (NCR5380_read(C400_CONTROL_STATUS_REG) & CSR_GATED_53C80_IRQ) {
+		if (NCR5380_read(hostdata->c400_ctl_status) & CSR_GATED_53C80_IRQ) {
 			printk(KERN_ERR "53C400r: Got 53C80_IRQ start=%d, blocks=%d\n", start, blocks);
 			return -1;
 		}
-		while (NCR5380_read(C400_CONTROL_STATUS_REG) & CSR_HOST_BUF_NOT_RDY);
+		while (NCR5380_read(hostdata->c400_ctl_status) & CSR_HOST_BUF_NOT_RDY)
+			; /* FIXME - no timeout */
 
 #ifndef SCSI_G_NCR5380_MEM
-		{
-			int i;
-			for (i = 0; i < 128; i++)
-				dst[start + i] = NCR5380_read(C400_HOST_BUFFER);
-		}
+		insb(instance->io_port + hostdata->c400_host_buf,
+							dst + start, 128);
 #else
 		/* implies SCSI_G_NCR5380_MEM */
 		memcpy_fromio(dst + start,
@@ -558,17 +563,12 @@ static inline int NCR5380_pread(struct Scsi_Host *instance, unsigned char *dst,
 	}
 
 	if (blocks) {
-		while (NCR5380_read(C400_CONTROL_STATUS_REG) & CSR_HOST_BUF_NOT_RDY)
-		{
-			// FIXME - no timeout
-		}
+		while (NCR5380_read(hostdata->c400_ctl_status) & CSR_HOST_BUF_NOT_RDY)
+			; /* FIXME - no timeout */
 
 #ifndef SCSI_G_NCR5380_MEM
-		{
-			int i;	
-			for (i = 0; i < 128; i++)
-				dst[start + i] = NCR5380_read(C400_HOST_BUFFER);
-		}
+		insb(instance->io_port + hostdata->c400_host_buf,
+							dst + start, 128);
 #else
 		/* implies SCSI_G_NCR5380_MEM */
 		memcpy_fromio(dst + start,
@@ -578,7 +578,7 @@ static inline int NCR5380_pread(struct Scsi_Host *instance, unsigned char *dst,
 		blocks--;
 	}
 
-	if (!(NCR5380_read(C400_CONTROL_STATUS_REG) & CSR_GATED_53C80_IRQ))
+	if (!(NCR5380_read(hostdata->c400_ctl_status) & CSR_GATED_53C80_IRQ))
 		printk("53C400r: no 53C80 gated irq after transfer");
 
 #if 0
@@ -586,7 +586,7 @@ static inline int NCR5380_pread(struct Scsi_Host *instance, unsigned char *dst,
 	 *	DON'T DO THIS - THEY NEVER ARRIVE!
 	 */
 	printk("53C400r: Waiting for 53C80 registers\n");
-	while (NCR5380_read(C400_CONTROL_STATUS_REG) & CSR_53C80_REG)
+	while (NCR5380_read(hostdata->c400_ctl_status) & CSR_53C80_REG)
 		;
 #endif
 	if (!(NCR5380_read(BUS_AND_STATUS_REG) & BASR_END_DMA_TRANSFER))
@@ -607,32 +607,26 @@ static inline int NCR5380_pread(struct Scsi_Host *instance, unsigned char *dst,
 
 static inline int NCR5380_pwrite(struct Scsi_Host *instance, unsigned char *src, int len)
 {
-#ifdef SCSI_G_NCR5380_MEM
 	struct NCR5380_hostdata *hostdata = shost_priv(instance);
-#endif
 	int blocks = len / 128;
 	int start = 0;
-	int bl;
 	int i;
 
-	NCR5380_write(C400_CONTROL_STATUS_REG, CSR_BASE);
-	NCR5380_write(C400_BLOCK_COUNTER_REG, blocks);
+	NCR5380_write(hostdata->c400_ctl_status, CSR_BASE);
+	NCR5380_write(hostdata->c400_blk_cnt, blocks);
 	while (1) {
-		if (NCR5380_read(C400_CONTROL_STATUS_REG) & CSR_GATED_53C80_IRQ) {
+		if (NCR5380_read(hostdata->c400_ctl_status) & CSR_GATED_53C80_IRQ) {
 			printk(KERN_ERR "53C400w: Got 53C80_IRQ start=%d, blocks=%d\n", start, blocks);
 			return -1;
 		}
 
-		if ((bl = NCR5380_read(C400_BLOCK_COUNTER_REG)) == 0) {
+		if (NCR5380_read(hostdata->c400_blk_cnt) == 0)
 			break;
-		}
-		while (NCR5380_read(C400_CONTROL_STATUS_REG) & CSR_HOST_BUF_NOT_RDY)
+		while (NCR5380_read(hostdata->c400_ctl_status) & CSR_HOST_BUF_NOT_RDY)
 			; // FIXME - timeout
 #ifndef SCSI_G_NCR5380_MEM
-		{
-			for (i = 0; i < 128; i++)
-				NCR5380_write(C400_HOST_BUFFER, src[start + i]);
-		}
+		outsb(instance->io_port + hostdata->c400_host_buf,
+							src + start, 128);
 #else
 		/* implies SCSI_G_NCR5380_MEM */
 		memcpy_toio(hostdata->iomem + NCR53C400_host_buffer,
@@ -642,14 +636,12 @@ static inline int NCR5380_pwrite(struct Scsi_Host *instance, unsigned char *src,
 		blocks--;
 	}
 	if (blocks) {
-		while (NCR5380_read(C400_CONTROL_STATUS_REG) & CSR_HOST_BUF_NOT_RDY)
+		while (NCR5380_read(hostdata->c400_ctl_status) & CSR_HOST_BUF_NOT_RDY)
 			; // FIXME - no timeout
 
 #ifndef SCSI_G_NCR5380_MEM
-		{
-			for (i = 0; i < 128; i++)
-				NCR5380_write(C400_HOST_BUFFER, src[start + i]);
-		}
+		outsb(instance->io_port + hostdata->c400_host_buf,
+							src + start, 128);
 #else
 		/* implies SCSI_G_NCR5380_MEM */
 		memcpy_toio(hostdata->iomem + NCR53C400_host_buffer,
@@ -661,7 +653,7 @@ static inline int NCR5380_pwrite(struct Scsi_Host *instance, unsigned char *src,
 
 #if 0
 	printk("53C400w: waiting for registers to be available\n");
-	THEY NEVER DO ! while (NCR5380_read(C400_CONTROL_STATUS_REG) & CSR_53C80_REG);
+	THEY NEVER DO ! while (NCR5380_read(hostdata->c400_ctl_status) & CSR_53C80_REG);
 	printk("53C400w: Got em\n");
 #endif
 
@@ -669,7 +661,7 @@ static inline int NCR5380_pwrite(struct Scsi_Host *instance, unsigned char *src,
 	/* All documentation says to check for this. Maybe my hardware is too
 	 * fast. Waiting for it seems to work fine! KLL
 	 */
-	while (!(i = NCR5380_read(C400_CONTROL_STATUS_REG) & CSR_GATED_53C80_IRQ))
+	while (!(i = NCR5380_read(hostdata->c400_ctl_status) & CSR_GATED_53C80_IRQ))
 		;	// FIXME - no timeout
 
 	/*
diff --git a/drivers/scsi/g_NCR5380.h b/drivers/scsi/g_NCR5380.h
index fd201e9..c5e57b7 100644
--- a/drivers/scsi/g_NCR5380.h
+++ b/drivers/scsi/g_NCR5380.h
@@ -29,7 +29,6 @@
 
 #define NCR5380_map_type int
 #define NCR5380_map_name port
-#define NCR53C400_register_offset 0
 
 #ifdef CONFIG_SCSI_GENERIC_NCR53C400
 #define NCR5380_region_size 16
@@ -42,7 +41,10 @@
 #define NCR5380_write(reg, value) \
 	outb(value, instance->io_port + (reg))
 
-#define NCR5380_implementation_fields /* none */
+#define NCR5380_implementation_fields \
+	int c400_ctl_status; \
+	int c400_blk_cnt; \
+	int c400_host_buf;
 
 #else 
 /* therefore SCSI_G_NCR5380_MEM */
@@ -50,7 +52,6 @@
 
 #define NCR5380_map_type unsigned long
 #define NCR5380_map_name base
-#define NCR53C400_register_offset 0x108
 #define NCR53C400_mem_base 0x3880
 #define NCR53C400_host_buffer 0x3900
 #define NCR5380_region_size 0x3a00
@@ -63,7 +64,10 @@
 	       NCR53C400_mem_base + (reg))
 
 #define NCR5380_implementation_fields \
-    void __iomem *iomem;
+	void __iomem *iomem; \
+	int c400_ctl_status; \
+	int c400_blk_cnt; \
+	int c400_host_buf;
 
 #endif
 
-- 
Ondrej Zary


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

* [PATCH v2 74/71] ncr5380: Enable PDMA for NCR53C400A
  2015-11-18  8:34 ` Finn Thain
                   ` (83 preceding siblings ...)
  (?)
@ 2015-12-06 22:21 ` Ondrej Zary
  2015-12-08  2:05   ` Finn Thain
  -1 siblings, 1 reply; 268+ messages in thread
From: Ondrej Zary @ 2015-12-06 22:21 UTC (permalink / raw)
  To: Finn Thain, Michael Schmitz, linux-m68k, linux-scsi, linux-kernel

Add I/O register mapping for NCR53C400A and enable PDMA mode to
improve performance and fix non-working IRQ.

Tested with HP C2502 (and user-space enabler).

Signed-off-by: Ondrej Zary <linux@rainbow-software.org>
---
 drivers/scsi/g_NCR5380.c |   14 +++++++++++---
 1 file changed, 11 insertions(+), 3 deletions(-)

diff --git a/drivers/scsi/g_NCR5380.c b/drivers/scsi/g_NCR5380.c
index 86740fd..099fdac 100644
--- a/drivers/scsi/g_NCR5380.c
+++ b/drivers/scsi/g_NCR5380.c
@@ -324,7 +324,7 @@ static int __init generic_NCR5380_detect(struct scsi_host_template *tpnt)
 #endif
 			break;
 		case BOARD_NCR53C400A:
-			flags = FLAG_NO_PSEUDO_DMA;
+			flags = FLAG_NO_DMA_FIXUP;
 			ports = ncr_53c400a_ports;
 			break;
 		case BOARD_DTC3181E:
@@ -406,11 +406,18 @@ static int __init generic_NCR5380_detect(struct scsi_host_template *tpnt)
 		 * On NCR53C400 boards, NCR5380 registers are mapped 8 past
 		 * the base address.
 		 */
-		if (overrides[current_override].board == BOARD_NCR53C400) {
+		switch (overrides[current_override].board) {
+		case BOARD_NCR53C400:
 			instance->io_port += 8;
 			hostdata->c400_ctl_status = 0;
 			hostdata->c400_blk_cnt = 1;
 			hostdata->c400_host_buf = 4;
+			break;
+		case BOARD_NCR53C400A:
+			hostdata->c400_ctl_status = 9;
+			hostdata->c400_blk_cnt = 10;
+			hostdata->c400_host_buf = 8;
+			break;
 		}
 #else
 		instance->base = overrides[current_override].NCR5380_map_name;
@@ -425,7 +432,8 @@ static int __init generic_NCR5380_detect(struct scsi_host_template *tpnt)
 		if (NCR5380_init(instance, flags))
 			goto out_unregister;
 
-		if (overrides[current_override].board == BOARD_NCR53C400)
+		if (overrides[current_override].board == BOARD_NCR53C400 ||
+		    overrides[current_override].board == BOARD_NCR53C400A)
 			NCR5380_write(hostdata->c400_ctl_status, CSR_BASE);
 
 		NCR5380_maybe_reset_bus(instance);
-- 
Ondrej Zary


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

* Re: [PATCH 76/71] ncr5380: Enable PDMA for DTC chips
  2015-12-06  3:40   ` Finn Thain
@ 2015-12-06 22:47     ` Ondrej Zary
  0 siblings, 0 replies; 268+ messages in thread
From: Ondrej Zary @ 2015-12-06 22:47 UTC (permalink / raw)
  To: Finn Thain; +Cc: Michael Schmitz, linux-m68k, linux-scsi, linux-kernel

On Sunday 06 December 2015 04:40:56 Finn Thain wrote:
> 
> On Fri, 4 Dec 2015, Ondrej Zary wrote:
> 
> > Add I/O register mapping for DTC chips and enable PDMA mode.
> > 
> > These chips have 16-bit wide HOST BUFFER register (counter register at
> > offset 0x0d increments by 2 on each HOST BUFFER read). Detect it
> > automatically.
> > 
> > Large PIO transfers crash at least the DTCT-436P chip (all reads result
> > in 0xFF) so this patch actually makes it work.
> > 
> > The chip also crashes when we bang the C400 host status register too
> > heavily after PDMA write - a small udelay is needed.
> > 
> > Tested on DTCT-436P and verified that it does not break 53C400A.
> > 
> > Signed-off-by: Ondrej Zary <linux@rainbow-software.org>
> > ---
> >  drivers/scsi/g_NCR5380.c |   59 ++++++++++++++++++++++++++++------------------
> >  drivers/scsi/g_NCR5380.h |    4 +++-
> >  2 files changed, 39 insertions(+), 24 deletions(-)
> > 
> > diff --git a/drivers/scsi/g_NCR5380.c b/drivers/scsi/g_NCR5380.c
> > index 85da3c2..9816b81 100644
> > --- a/drivers/scsi/g_NCR5380.c
> > +++ b/drivers/scsi/g_NCR5380.c
> > @@ -328,7 +328,7 @@ static int __init generic_NCR5380_detect(struct scsi_host_template *tpnt)
> >  			ports = ncr_53c400a_ports;
> >  			break;
> >  		case BOARD_DTC3181E:
> > -			flags = FLAG_NO_PSEUDO_DMA;
> > +			flags = FLAG_NO_DMA_FIXUP;
> 
> Nice!
> 
> >  			ports = dtc_3181e_ports;
> >  			break;
> >  		}
> > @@ -412,10 +412,12 @@ static int __init generic_NCR5380_detect(struct scsi_host_template *tpnt)
> >  			hostdata->c400_blk_cnt = 1;
> >  			hostdata->c400_host_buf = 4;
> >  		}
> > -		if (overrides[current_override].board == BOARD_NCR53C400A) {
> > +		if (overrides[current_override].board == BOARD_NCR53C400A ||
> > +		    overrides[current_override].board == BOARD_DTC3181E) {
> >  			hostdata->c400_ctl_status = 9;
> >  			hostdata->c400_blk_cnt = 10;
> >  			hostdata->c400_host_buf = 8;
> > +			hostdata->c400_host_idx = 13;
> >  		}
> >  #else
> >  		instance->base = overrides[current_override].NCR5380_map_name;
> > @@ -430,8 +432,20 @@ static int __init generic_NCR5380_detect(struct scsi_host_template *tpnt)
> >  		if (NCR5380_init(instance, flags))
> >  			goto out_unregister;
> >  
> > +#ifndef SCSI_G_NCR5380_MEM
> > +		/* read initial value of index register */
> > +		i = NCR5380_read(hostdata->c400_host_idx);
> > +		/* read something from host buffer */
> > +		NCR5380_read(hostdata->c400_host_buf);
> > +		/* I/O width = index register increment */
> > +		hostdata->io_width = NCR5380_read(hostdata->c400_host_idx) - i;
> > +		if (hostdata->io_width < 0)
> > +			hostdata->io_width += 128;
> > +#endif
> 
> Will the result depend on the initial state of the chip, such as
> CSR_TRANS_DIR or CSR_HOST_BUF_NOT_RDY?
> 
> It is possible to generate an interrupt with the buffer read, which should 
> be masked at the chip.
> 
> This buffer read may cause the 53C400 control logic to signal the 53C80 
> core. I suppose it is unlikely to cause any signalling on the SCSI bus 
> unless the 53C80 happened to be in DMA mode.
> 
> The possibility that io_width == 0 is not handled; wouldn't this result 
> indicate that PDMA shouldn't be used?
> 
> io_width can be calculated without a conditional statement, which may be 
> easier to read.
> 
> Can we be confident that detection will fail for all devices that don't 
> support word-sized IO, to avoid a regression?
> 
> The patch seems to assume that no memory-mapped card needs word-sized IO 
> for PDMA. Can you confirm?

My memory-mapped Canon card is a 8-bit ISA card so it can't do 16-bit I/O by
definition. Don't know if there are any 16-bit memory-mapped cards.

> The previous version of this patch was simpler and more predictable. You 
> enabled word-size IO for DTC3181E which is testable. Does this version 
> benefit any other cards?

Probably not. Looks like this code creates more problems that it solves.
I'll revert to the original approach.

> > +
> >  		if (overrides[current_override].board == BOARD_NCR53C400 ||
> > -		    overrides[current_override].board == BOARD_NCR53C400A)
> > +		    overrides[current_override].board == BOARD_NCR53C400A ||
> > +		    overrides[current_override].board == BOARD_DTC3181E)
> >  			NCR5380_write(hostdata->c400_ctl_status, CSR_BASE);
> >  
> >  		NCR5380_maybe_reset_bus(instance);
> > @@ -558,11 +572,10 @@ static inline int NCR5380_pread(struct Scsi_Host *instance, unsigned char *dst,
> >  		while (NCR5380_read(hostdata->c400_ctl_status) & CSR_HOST_BUF_NOT_RDY);
> >  
> >  #ifndef SCSI_G_NCR5380_MEM
> > -		{
> > -			int i;
> > -			for (i = 0; i < 128; i++)
> > -				dst[start + i] = NCR5380_read(hostdata->c400_host_buf);
> > -		}
> > +		if (hostdata->io_width == 2)
> > +			insw(instance->io_port + hostdata->c400_host_buf, dst + start, 64);
> > +		else
> > +			insb(instance->io_port + hostdata->c400_host_buf, dst + start, 128);
> >  #else
> >  		/* implies SCSI_G_NCR5380_MEM */
> >  		memcpy_fromio(dst + start,
> > @@ -579,11 +592,10 @@ static inline int NCR5380_pread(struct Scsi_Host *instance, unsigned char *dst,
> >  		}
> >  
> >  #ifndef SCSI_G_NCR5380_MEM
> > -		{
> > -			int i;	
> > -			for (i = 0; i < 128; i++)
> > -				dst[start + i] = NCR5380_read(hostdata->c400_host_buf);
> > -		}
> > +		if (hostdata->io_width == 2)
> > +			insw(instance->io_port + hostdata->c400_host_buf, dst + start, 64);
> > +		else
> > +			insb(instance->io_port + hostdata->c400_host_buf, dst + start, 128);
> >  #else
> >  		/* implies SCSI_G_NCR5380_MEM */
> >  		memcpy_fromio(dst + start,
> > @@ -642,10 +654,10 @@ static inline int NCR5380_pwrite(struct Scsi_Host *instance, unsigned char *src,
> >  		while (NCR5380_read(hostdata->c400_ctl_status) & CSR_HOST_BUF_NOT_RDY)
> >  			; // FIXME - timeout
> >  #ifndef SCSI_G_NCR5380_MEM
> > -		{
> > -			for (i = 0; i < 128; i++)
> > -				NCR5380_write(hostdata->c400_host_buf, src[start + i]);
> > -		}
> > +		if (hostdata->io_width == 2)
> > +			outsw(instance->io_port + hostdata->c400_host_buf, src + start, 64);
> > +		else
> > +			outsb(instance->io_port + hostdata->c400_host_buf, src + start, 128);
> >  #else
> >  		/* implies SCSI_G_NCR5380_MEM */
> >  		memcpy_toio(hostdata->iomem + NCR53C400_host_buffer,
> > @@ -657,12 +669,11 @@ static inline int NCR5380_pwrite(struct Scsi_Host *instance, unsigned char *src,
> >  	if (blocks) {
> >  		while (NCR5380_read(hostdata->c400_ctl_status) & CSR_HOST_BUF_NOT_RDY)
> >  			; // FIXME - no timeout
> > -
> >  #ifndef SCSI_G_NCR5380_MEM
> > -		{
> > -			for (i = 0; i < 128; i++)
> > -				NCR5380_write(hostdata->c400_host_buf, src[start + i]);
> > -		}
> > +		if (hostdata->io_width == 2)
> > +			outsw(instance->io_port + hostdata->c400_host_buf, src + start, 64);
> > +		else
> > +			outsb(instance->io_port + hostdata->c400_host_buf, src + start, 128);
> >  #else
> >  		/* implies SCSI_G_NCR5380_MEM */
> >  		memcpy_toio(hostdata->iomem + NCR53C400_host_buffer,
> > @@ -682,8 +693,10 @@ static inline int NCR5380_pwrite(struct Scsi_Host *instance, unsigned char *src,
> >  	/* All documentation says to check for this. Maybe my hardware is too
> >  	 * fast. Waiting for it seems to work fine! KLL
> >  	 */
> > -	while (!(i = NCR5380_read(hostdata->c400_ctl_status) & CSR_GATED_53C80_IRQ))
> > +	while (!(i = NCR5380_read(hostdata->c400_ctl_status) & CSR_GATED_53C80_IRQ)) {
> > +		udelay(4); /* DTC436 chip hangs without this */
> >  		;	// FIXME - no timeout
> > +	}
> 
> When you added the braces, the lone semicolon became redundant. But I 
> think the entire loop is bogus.
> 
> Why do we wait for CSR_GATED_53C80_IRQ? I can understand testing it during 
> a transfer but why afterwards? (The core driver could test for the IRQ 
> flag in the Bus and Status Register, at the end of a DMA, if this scsi 
> host has no IRQ line.)
> 
> The comments and the 53C400 datasheet say we should instead wait for 
> CSR_53C80_REG. I agree. The g_NCR5380 wrapper driver can't safely return 
> control to the core driver unless the 53C80 registers are available.
> 
> The algorithm in the datasheet waits for CSR_53C80_REG before checking 
> BASR_END_DMA_TRANSFER, checking interrupt flags, disabling DMA mode etc. 
> 
> g_NCR5380.c has an '#if 0' around the BASR_END_DMA_TRANSFER check, because 
> it doesn't wait for CSR_53C80_REG. Does NCR's algorithm work with your 
> cards?

I'll leave this to patch 77. I guess that it will work properly without
waiting for CSR_GATED_53C80_IRQ.

> >  
> >  	/*
> >  	 * I know. i is certainly != 0 here but the loop is new. See previous
> > diff --git a/drivers/scsi/g_NCR5380.h b/drivers/scsi/g_NCR5380.h
> > index c5e57b7..b3936aa 100644
> > --- a/drivers/scsi/g_NCR5380.h
> > +++ b/drivers/scsi/g_NCR5380.h
> > @@ -44,7 +44,9 @@
> >  #define NCR5380_implementation_fields \
> >  	int c400_ctl_status; \
> >  	int c400_blk_cnt; \
> > -	int c400_host_buf;
> > +	int c400_host_buf; \
> > +	int c400_host_idx; \
> > +	int io_width;
> >  
> >  #else 
> >  /* therefore SCSI_G_NCR5380_MEM */
> > 
> 


-- 
Ondrej Zary

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

* [PATCH v2 76/71] ncr5380: Enable PDMA for DTC chips
  2015-11-18  8:34 ` Finn Thain
                   ` (84 preceding siblings ...)
  (?)
@ 2015-12-06 22:55 ` Ondrej Zary
  -1 siblings, 0 replies; 268+ messages in thread
From: Ondrej Zary @ 2015-12-06 22:55 UTC (permalink / raw)
  To: Finn Thain, Michael Schmitz, linux-m68k, linux-scsi, linux-kernel

Add I/O register mapping for DTC chips and enable PDMA mode.

These chips have 16-bit wide HOST BUFFER register and it must be read
by 16-bit accesses (we lose data otherwise).

Large PIO transfers crash at least the DTCT-436P chip (all reads result
in 0xFF) so this patch actually makes it work.

The chip also crashes when we bang the C400 host status register too
heavily after PDMA write - a small udelay is needed.

Tested on DTCT-436P and verified that it does not break 53C400A.

Signed-off-by: Ondrej Zary <linux@rainbow-software.org>
---
 drivers/scsi/g_NCR5380.c |   40 ++++++++++++++++++++++++++++++++--------
 drivers/scsi/g_NCR5380.h |    4 +++-
 2 files changed, 35 insertions(+), 9 deletions(-)

diff --git a/drivers/scsi/g_NCR5380.c b/drivers/scsi/g_NCR5380.c
index 578d4fa..038dddf 100644
--- a/drivers/scsi/g_NCR5380.c
+++ b/drivers/scsi/g_NCR5380.c
@@ -328,7 +328,7 @@ static int __init generic_NCR5380_detect(struct scsi_host_template *tpnt)
 			ports = ncr_53c400a_ports;
 			break;
 		case BOARD_DTC3181E:
-			flags = FLAG_NO_PSEUDO_DMA;
+			flags = FLAG_NO_DMA_FIXUP;
 			ports = dtc_3181e_ports;
 			break;
 		}
@@ -401,6 +401,7 @@ static int __init generic_NCR5380_detect(struct scsi_host_template *tpnt)
 #ifndef SCSI_G_NCR5380_MEM
 		instance->io_port = overrides[current_override].NCR5380_map_name;
 		instance->n_io_port = region_size;
+		hostdata->io_width = 1; /* 8-bit PDMA by default */
 
 		/*
 		 * On NCR53C400 boards, NCR5380 registers are mapped 8 past
@@ -413,10 +414,14 @@ static int __init generic_NCR5380_detect(struct scsi_host_template *tpnt)
 			hostdata->c400_blk_cnt = 1;
 			hostdata->c400_host_buf = 4;
 			break;
+		case BOARD_DTC3181E:
+			hostdata->io_width = 2;	/* 16-bit PDMA */
+			/* fall through */
 		case BOARD_NCR53C400A:
 			hostdata->c400_ctl_status = 9;
 			hostdata->c400_blk_cnt = 10;
 			hostdata->c400_host_buf = 8;
+			hostdata->c400_host_idx = 13;
 			break;
 		}
 #else
@@ -433,7 +438,8 @@ static int __init generic_NCR5380_detect(struct scsi_host_template *tpnt)
 			goto out_unregister;
 
 		if (overrides[current_override].board == BOARD_NCR53C400 ||
-		    overrides[current_override].board == BOARD_NCR53C400A)
+		    overrides[current_override].board == BOARD_NCR53C400A ||
+		    overrides[current_override].board == BOARD_DTC3181E)
 			NCR5380_write(hostdata->c400_ctl_status, CSR_BASE);
 
 		NCR5380_maybe_reset_bus(instance);
@@ -559,7 +565,11 @@ static inline int NCR5380_pread(struct Scsi_Host *instance, unsigned char *dst,
 			; /* FIXME - no timeout */
 
 #ifndef SCSI_G_NCR5380_MEM
-		insb(instance->io_port + hostdata->c400_host_buf,
+		if (hostdata->io_width == 2)
+			insw(instance->io_port + hostdata->c400_host_buf,
+							dst + start, 64);
+		else
+			insb(instance->io_port + hostdata->c400_host_buf,
 							dst + start, 128);
 #else
 		/* implies SCSI_G_NCR5380_MEM */
@@ -575,7 +585,11 @@ static inline int NCR5380_pread(struct Scsi_Host *instance, unsigned char *dst,
 			; /* FIXME - no timeout */
 
 #ifndef SCSI_G_NCR5380_MEM
-		insb(instance->io_port + hostdata->c400_host_buf,
+		if (hostdata->io_width == 2)
+			insw(instance->io_port + hostdata->c400_host_buf,
+							dst + start, 64);
+		else
+			insb(instance->io_port + hostdata->c400_host_buf,
 							dst + start, 128);
 #else
 		/* implies SCSI_G_NCR5380_MEM */
@@ -633,7 +647,11 @@ static inline int NCR5380_pwrite(struct Scsi_Host *instance, unsigned char *src,
 		while (NCR5380_read(hostdata->c400_ctl_status) & CSR_HOST_BUF_NOT_RDY)
 			; // FIXME - timeout
 #ifndef SCSI_G_NCR5380_MEM
-		outsb(instance->io_port + hostdata->c400_host_buf,
+		if (hostdata->io_width == 2)
+			outsw(instance->io_port + hostdata->c400_host_buf,
+							src + start, 64);
+		else
+			outsb(instance->io_port + hostdata->c400_host_buf,
 							src + start, 128);
 #else
 		/* implies SCSI_G_NCR5380_MEM */
@@ -648,7 +666,11 @@ static inline int NCR5380_pwrite(struct Scsi_Host *instance, unsigned char *src,
 			; // FIXME - no timeout
 
 #ifndef SCSI_G_NCR5380_MEM
-		outsb(instance->io_port + hostdata->c400_host_buf,
+		if (hostdata->io_width == 2)
+			outsw(instance->io_port + hostdata->c400_host_buf,
+							src + start, 64);
+		else
+			outsb(instance->io_port + hostdata->c400_host_buf,
 							src + start, 128);
 #else
 		/* implies SCSI_G_NCR5380_MEM */
@@ -669,8 +691,10 @@ static inline int NCR5380_pwrite(struct Scsi_Host *instance, unsigned char *src,
 	/* All documentation says to check for this. Maybe my hardware is too
 	 * fast. Waiting for it seems to work fine! KLL
 	 */
-	while (!(i = NCR5380_read(hostdata->c400_ctl_status) & CSR_GATED_53C80_IRQ))
-		;	// FIXME - no timeout
+	while (!(i = NCR5380_read(hostdata->c400_ctl_status) & CSR_GATED_53C80_IRQ)) {
+		udelay(4); /* DTC436 chip hangs without this */
+		/* FIXME - no timeout */
+	}
 
 	/*
 	 * I know. i is certainly != 0 here but the loop is new. See previous
diff --git a/drivers/scsi/g_NCR5380.h b/drivers/scsi/g_NCR5380.h
index c5e57b7..b3936aa 100644
--- a/drivers/scsi/g_NCR5380.h
+++ b/drivers/scsi/g_NCR5380.h
@@ -44,7 +44,9 @@
 #define NCR5380_implementation_fields \
 	int c400_ctl_status; \
 	int c400_blk_cnt; \
-	int c400_host_buf;
+	int c400_host_buf; \
+	int c400_host_idx; \
+	int io_width;
 
 #else 
 /* therefore SCSI_G_NCR5380_MEM */
-- 
Ondrej Zary


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

* [PATCH v2 77/71] ncr5380: Fix wait for 53C80 registers registers after PDMA
  2015-11-18  8:34 ` Finn Thain
                   ` (85 preceding siblings ...)
  (?)
@ 2015-12-06 23:17 ` Ondrej Zary
  2015-12-07  3:16   ` Finn Thain
  -1 siblings, 1 reply; 268+ messages in thread
From: Ondrej Zary @ 2015-12-06 23:17 UTC (permalink / raw)
  To: Finn Thain, Michael Schmitz, linux-m68k, linux-scsi, linux-kernel

The check for 53C80 registers accessibility was commented out because
it was broken (inverted). Fix and enable it.

Signed-off-by: Ondrej Zary <linux@rainbow-software.org>
---
 drivers/scsi/g_NCR5380.c |   37 ++++++-------------------------------
 1 file changed, 6 insertions(+), 31 deletions(-)

diff --git a/drivers/scsi/g_NCR5380.c b/drivers/scsi/g_NCR5380.c
index 038dddf..a7479c6 100644
--- a/drivers/scsi/g_NCR5380.c
+++ b/drivers/scsi/g_NCR5380.c
@@ -603,14 +603,10 @@ static inline int NCR5380_pread(struct Scsi_Host *instance, unsigned char *dst,
 	if (!(NCR5380_read(hostdata->c400_ctl_status) & CSR_GATED_53C80_IRQ))
 		printk("53C400r: no 53C80 gated irq after transfer");
 
-#if 0
-	/*
-	 *	DON'T DO THIS - THEY NEVER ARRIVE!
-	 */
-	printk("53C400r: Waiting for 53C80 registers\n");
-	while (NCR5380_read(hostdata->c400_ctl_status) & CSR_53C80_REG)
+	/* wait for 53C80 registers to be available */
+	while (!(NCR5380_read(hostdata->c400_ctl_status) & CSR_53C80_REG))
 		;
-#endif
+
 	if (!(NCR5380_read(BUS_AND_STATUS_REG) & BASR_END_DMA_TRANSFER))
 		printk(KERN_ERR "53C400r: no end dma signal\n");
 		
@@ -632,7 +628,6 @@ static inline int NCR5380_pwrite(struct Scsi_Host *instance, unsigned char *src,
 	struct NCR5380_hostdata *hostdata = shost_priv(instance);
 	int blocks = len / 128;
 	int start = 0;
-	int i;
 
 	NCR5380_write(hostdata->c400_ctl_status, CSR_BASE);
 	NCR5380_write(hostdata->c400_blk_cnt, blocks);
@@ -681,36 +676,16 @@ static inline int NCR5380_pwrite(struct Scsi_Host *instance, unsigned char *src,
 		blocks--;
 	}
 
-#if 0
-	printk("53C400w: waiting for registers to be available\n");
-	THEY NEVER DO ! while (NCR5380_read(hostdata->c400_ctl_status) & CSR_53C80_REG);
-	printk("53C400w: Got em\n");
-#endif
-
-	/* Let's wait for this instead - could be ugly */
-	/* All documentation says to check for this. Maybe my hardware is too
-	 * fast. Waiting for it seems to work fine! KLL
-	 */
-	while (!(i = NCR5380_read(hostdata->c400_ctl_status) & CSR_GATED_53C80_IRQ)) {
+	/* wait for 53C80 registers to be available */
+	while (!(NCR5380_read(hostdata->c400_ctl_status) & CSR_53C80_REG)) {
 		udelay(4); /* DTC436 chip hangs without this */
 		/* FIXME - no timeout */
 	}
 
-	/*
-	 * I know. i is certainly != 0 here but the loop is new. See previous
-	 * comment.
-	 */
-	if (i) {
-		if (!((i = NCR5380_read(BUS_AND_STATUS_REG)) & BASR_END_DMA_TRANSFER))
-			printk(KERN_ERR "53C400w: No END OF DMA bit - WHOOPS! BASR=%0x\n", i);
-	} else
-		printk(KERN_ERR "53C400w: no 53C80 gated irq after transfer (last block)\n");
-
-#if 0
 	if (!(NCR5380_read(BUS_AND_STATUS_REG) & BASR_END_DMA_TRANSFER)) {
 		printk(KERN_ERR "53C400w: no end dma signal\n");
 	}
-#endif
+
 	while (!(NCR5380_read(TARGET_COMMAND_REG) & TCR_LAST_BYTE_SENT))
 		; 	// TIMEOUT
 	return 0;
-- 
Ondrej Zary


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

* [PATCH v3 76/71] ncr5380: Enable PDMA for DTC chips
  2015-11-18  8:34 ` Finn Thain
                   ` (86 preceding siblings ...)
  (?)
@ 2015-12-06 23:20 ` Ondrej Zary
  -1 siblings, 0 replies; 268+ messages in thread
From: Ondrej Zary @ 2015-12-06 23:20 UTC (permalink / raw)
  To: Finn Thain, Michael Schmitz, linux-m68k, linux-scsi, linux-kernel

Add I/O register mapping for DTC chips and enable PDMA mode.

These chips have 16-bit wide HOST BUFFER register and it must be read
by 16-bit accesses (we lose data otherwise).

Large PIO transfers crash at least the DTCT-436P chip (all reads result
in 0xFF) so this patch actually makes it work.

The chip also crashes when we bang the C400 host status register too
heavily after PDMA write - a small udelay is needed.

Tested on DTCT-436P and verified that it does not break 53C400A.

Signed-off-by: Ondrej Zary <linux@rainbow-software.org>
---
 drivers/scsi/g_NCR5380.c |   39 +++++++++++++++++++++++++++++++--------
 drivers/scsi/g_NCR5380.h |    3 ++-
 2 files changed, 33 insertions(+), 9 deletions(-)

diff --git a/drivers/scsi/g_NCR5380.c b/drivers/scsi/g_NCR5380.c
index 578d4fa..ef719cf0 100644
--- a/drivers/scsi/g_NCR5380.c
+++ b/drivers/scsi/g_NCR5380.c
@@ -328,7 +328,7 @@ static int __init generic_NCR5380_detect(struct scsi_host_template *tpnt)
 			ports = ncr_53c400a_ports;
 			break;
 		case BOARD_DTC3181E:
-			flags = FLAG_NO_PSEUDO_DMA;
+			flags = FLAG_NO_DMA_FIXUP;
 			ports = dtc_3181e_ports;
 			break;
 		}
@@ -401,6 +401,7 @@ static int __init generic_NCR5380_detect(struct scsi_host_template *tpnt)
 #ifndef SCSI_G_NCR5380_MEM
 		instance->io_port = overrides[current_override].NCR5380_map_name;
 		instance->n_io_port = region_size;
+		hostdata->io_width = 1; /* 8-bit PDMA by default */
 
 		/*
 		 * On NCR53C400 boards, NCR5380 registers are mapped 8 past
@@ -413,6 +414,9 @@ static int __init generic_NCR5380_detect(struct scsi_host_template *tpnt)
 			hostdata->c400_blk_cnt = 1;
 			hostdata->c400_host_buf = 4;
 			break;
+		case BOARD_DTC3181E:
+			hostdata->io_width = 2;	/* 16-bit PDMA */
+			/* fall through */
 		case BOARD_NCR53C400A:
 			hostdata->c400_ctl_status = 9;
 			hostdata->c400_blk_cnt = 10;
@@ -433,7 +437,8 @@ static int __init generic_NCR5380_detect(struct scsi_host_template *tpnt)
 			goto out_unregister;
 
 		if (overrides[current_override].board == BOARD_NCR53C400 ||
-		    overrides[current_override].board == BOARD_NCR53C400A)
+		    overrides[current_override].board == BOARD_NCR53C400A ||
+		    overrides[current_override].board == BOARD_DTC3181E)
 			NCR5380_write(hostdata->c400_ctl_status, CSR_BASE);
 
 		NCR5380_maybe_reset_bus(instance);
@@ -559,7 +564,11 @@ static inline int NCR5380_pread(struct Scsi_Host *instance, unsigned char *dst,
 			; /* FIXME - no timeout */
 
 #ifndef SCSI_G_NCR5380_MEM
-		insb(instance->io_port + hostdata->c400_host_buf,
+		if (hostdata->io_width == 2)
+			insw(instance->io_port + hostdata->c400_host_buf,
+							dst + start, 64);
+		else
+			insb(instance->io_port + hostdata->c400_host_buf,
 							dst + start, 128);
 #else
 		/* implies SCSI_G_NCR5380_MEM */
@@ -575,7 +584,11 @@ static inline int NCR5380_pread(struct Scsi_Host *instance, unsigned char *dst,
 			; /* FIXME - no timeout */
 
 #ifndef SCSI_G_NCR5380_MEM
-		insb(instance->io_port + hostdata->c400_host_buf,
+		if (hostdata->io_width == 2)
+			insw(instance->io_port + hostdata->c400_host_buf,
+							dst + start, 64);
+		else
+			insb(instance->io_port + hostdata->c400_host_buf,
 							dst + start, 128);
 #else
 		/* implies SCSI_G_NCR5380_MEM */
@@ -633,7 +646,11 @@ static inline int NCR5380_pwrite(struct Scsi_Host *instance, unsigned char *src,
 		while (NCR5380_read(hostdata->c400_ctl_status) & CSR_HOST_BUF_NOT_RDY)
 			; // FIXME - timeout
 #ifndef SCSI_G_NCR5380_MEM
-		outsb(instance->io_port + hostdata->c400_host_buf,
+		if (hostdata->io_width == 2)
+			outsw(instance->io_port + hostdata->c400_host_buf,
+							src + start, 64);
+		else
+			outsb(instance->io_port + hostdata->c400_host_buf,
 							src + start, 128);
 #else
 		/* implies SCSI_G_NCR5380_MEM */
@@ -648,7 +665,11 @@ static inline int NCR5380_pwrite(struct Scsi_Host *instance, unsigned char *src,
 			; // FIXME - no timeout
 
 #ifndef SCSI_G_NCR5380_MEM
-		outsb(instance->io_port + hostdata->c400_host_buf,
+		if (hostdata->io_width == 2)
+			outsw(instance->io_port + hostdata->c400_host_buf,
+							src + start, 64);
+		else
+			outsb(instance->io_port + hostdata->c400_host_buf,
 							src + start, 128);
 #else
 		/* implies SCSI_G_NCR5380_MEM */
@@ -669,8 +690,10 @@ static inline int NCR5380_pwrite(struct Scsi_Host *instance, unsigned char *src,
 	/* All documentation says to check for this. Maybe my hardware is too
 	 * fast. Waiting for it seems to work fine! KLL
 	 */
-	while (!(i = NCR5380_read(hostdata->c400_ctl_status) & CSR_GATED_53C80_IRQ))
-		;	// FIXME - no timeout
+	while (!(i = NCR5380_read(hostdata->c400_ctl_status) & CSR_GATED_53C80_IRQ)) {
+		udelay(4); /* DTC436 chip hangs without this */
+		/* FIXME - no timeout */
+	}
 
 	/*
 	 * I know. i is certainly != 0 here but the loop is new. See previous
diff --git a/drivers/scsi/g_NCR5380.h b/drivers/scsi/g_NCR5380.h
index c5e57b7..5ab64d9 100644
--- a/drivers/scsi/g_NCR5380.h
+++ b/drivers/scsi/g_NCR5380.h
@@ -44,7 +44,8 @@
 #define NCR5380_implementation_fields \
 	int c400_ctl_status; \
 	int c400_blk_cnt; \
-	int c400_host_buf;
+	int c400_host_buf; \
+	int io_width;
 
 #else 
 /* therefore SCSI_G_NCR5380_MEM */
-- 
Ondrej Zary


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

* Re: [PATCH v2 77/71] ncr5380: Fix wait for 53C80 registers registers after PDMA
  2015-12-06 23:17 ` [PATCH v2 77/71] ncr5380: Fix wait for 53C80 registers registers after PDMA Ondrej Zary
@ 2015-12-07  3:16   ` Finn Thain
  2015-12-07  8:08     ` Ondrej Zary
  0 siblings, 1 reply; 268+ messages in thread
From: Finn Thain @ 2015-12-07  3:16 UTC (permalink / raw)
  To: Ondrej Zary; +Cc: Michael Schmitz, linux-m68k, linux-scsi, linux-kernel


On Mon, 7 Dec 2015, Ondrej Zary wrote:

> The check for 53C80 registers accessibility was commented out because
> it was broken (inverted). Fix and enable it.
> 
> Signed-off-by: Ondrej Zary <linux@rainbow-software.org>
> ---
>  drivers/scsi/g_NCR5380.c |   37 ++++++-------------------------------
>  1 file changed, 6 insertions(+), 31 deletions(-)
> 
> diff --git a/drivers/scsi/g_NCR5380.c b/drivers/scsi/g_NCR5380.c
> index 038dddf..a7479c6 100644
> --- a/drivers/scsi/g_NCR5380.c
> +++ b/drivers/scsi/g_NCR5380.c
> @@ -603,14 +603,10 @@ static inline int NCR5380_pread(struct Scsi_Host *instance, unsigned char *dst,
>  	if (!(NCR5380_read(hostdata->c400_ctl_status) & CSR_GATED_53C80_IRQ))
>  		printk("53C400r: no 53C80 gated irq after transfer");
>  
> -#if 0
> -	/*
> -	 *	DON'T DO THIS - THEY NEVER ARRIVE!
> -	 */
> -	printk("53C400r: Waiting for 53C80 registers\n");
> -	while (NCR5380_read(hostdata->c400_ctl_status) & CSR_53C80_REG)
> +	/* wait for 53C80 registers to be available */
> +	while (!(NCR5380_read(hostdata->c400_ctl_status) & CSR_53C80_REG))
>  		;

In the previous patch, udelay(4) was added to a CSR_GATED_53C80_IRQ 
polling loop. It is interesting that you don't need it here when polling 
CSR_53C80_REG.

> -#endif
> +
>  	if (!(NCR5380_read(BUS_AND_STATUS_REG) & BASR_END_DMA_TRANSFER))
>  		printk(KERN_ERR "53C400r: no end dma signal\n");
>  		
> @@ -632,7 +628,6 @@ static inline int NCR5380_pwrite(struct Scsi_Host *instance, unsigned char *src,
>  	struct NCR5380_hostdata *hostdata = shost_priv(instance);
>  	int blocks = len / 128;
>  	int start = 0;
> -	int i;
>  
>  	NCR5380_write(hostdata->c400_ctl_status, CSR_BASE);
>  	NCR5380_write(hostdata->c400_blk_cnt, blocks);
> @@ -681,36 +676,16 @@ static inline int NCR5380_pwrite(struct Scsi_Host *instance, unsigned char *src,
>  		blocks--;
>  	}
>  
> -#if 0
> -	printk("53C400w: waiting for registers to be available\n");
> -	THEY NEVER DO ! while (NCR5380_read(hostdata->c400_ctl_status) & CSR_53C80_REG);
> -	printk("53C400w: Got em\n");
> -#endif
> -
> -	/* Let's wait for this instead - could be ugly */
> -	/* All documentation says to check for this. Maybe my hardware is too
> -	 * fast. Waiting for it seems to work fine! KLL
> -	 */
> -	while (!(i = NCR5380_read(hostdata->c400_ctl_status) & CSR_GATED_53C80_IRQ)) {
> +	/* wait for 53C80 registers to be available */
> +	while (!(NCR5380_read(hostdata->c400_ctl_status) & CSR_53C80_REG)) {
>  		udelay(4); /* DTC436 chip hangs without this */

... based on the above, this udelay is probably not needed.

(Or perhaps it is only needed once, in between the final host_buf register 
access and the first ctl_status access??)

Is there any reference in the docs to timing sensitivity?

>  		/* FIXME - no timeout */
>  	}
>  
> -	/*
> -	 * I know. i is certainly != 0 here but the loop is new. See previous
> -	 * comment.
> -	 */

Thanks for cleaning up this mess!

-- 

> -	if (i) {
> -		if (!((i = NCR5380_read(BUS_AND_STATUS_REG)) & BASR_END_DMA_TRANSFER))
> -			printk(KERN_ERR "53C400w: No END OF DMA bit - WHOOPS! BASR=%0x\n", i);
> -	} else
> -		printk(KERN_ERR "53C400w: no 53C80 gated irq after transfer (last block)\n");
> -
> -#if 0
>  	if (!(NCR5380_read(BUS_AND_STATUS_REG) & BASR_END_DMA_TRANSFER)) {
>  		printk(KERN_ERR "53C400w: no end dma signal\n");
>  	}
> -#endif
> +
>  	while (!(NCR5380_read(TARGET_COMMAND_REG) & TCR_LAST_BYTE_SENT))
>  		; 	// TIMEOUT
>  	return 0;
> 

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

* Re: [PATCH v2 77/71] ncr5380: Fix wait for 53C80 registers registers after PDMA
  2015-12-07  3:16   ` Finn Thain
@ 2015-12-07  8:08     ` Ondrej Zary
  0 siblings, 0 replies; 268+ messages in thread
From: Ondrej Zary @ 2015-12-07  8:08 UTC (permalink / raw)
  To: Finn Thain; +Cc: Michael Schmitz, linux-m68k, linux-scsi, linux-kernel

On Monday 07 December 2015 04:16:14 Finn Thain wrote:
> 
> On Mon, 7 Dec 2015, Ondrej Zary wrote:
> 
> > The check for 53C80 registers accessibility was commented out because
> > it was broken (inverted). Fix and enable it.
> > 
> > Signed-off-by: Ondrej Zary <linux@rainbow-software.org>
> > ---
> >  drivers/scsi/g_NCR5380.c |   37 ++++++-------------------------------
> >  1 file changed, 6 insertions(+), 31 deletions(-)
> > 
> > diff --git a/drivers/scsi/g_NCR5380.c b/drivers/scsi/g_NCR5380.c
> > index 038dddf..a7479c6 100644
> > --- a/drivers/scsi/g_NCR5380.c
> > +++ b/drivers/scsi/g_NCR5380.c
> > @@ -603,14 +603,10 @@ static inline int NCR5380_pread(struct Scsi_Host *instance, unsigned char *dst,
> >  	if (!(NCR5380_read(hostdata->c400_ctl_status) & CSR_GATED_53C80_IRQ))
> >  		printk("53C400r: no 53C80 gated irq after transfer");
> >  
> > -#if 0
> > -	/*
> > -	 *	DON'T DO THIS - THEY NEVER ARRIVE!
> > -	 */
> > -	printk("53C400r: Waiting for 53C80 registers\n");
> > -	while (NCR5380_read(hostdata->c400_ctl_status) & CSR_53C80_REG)
> > +	/* wait for 53C80 registers to be available */
> > +	while (!(NCR5380_read(hostdata->c400_ctl_status) & CSR_53C80_REG))
> >  		;
> 
> In the previous patch, udelay(4) was added to a CSR_GATED_53C80_IRQ 
> polling loop. It is interesting that you don't need it here when polling 
> CSR_53C80_REG.

Yes, it's weird. Reads work fine without the delay. Small writes work most of
the time without the delay but crash sometimes. Large writes crash the chip
consistently without the delay.

> > -#endif
> > +
> >  	if (!(NCR5380_read(BUS_AND_STATUS_REG) & BASR_END_DMA_TRANSFER))
> >  		printk(KERN_ERR "53C400r: no end dma signal\n");
> >  		
> > @@ -632,7 +628,6 @@ static inline int NCR5380_pwrite(struct Scsi_Host *instance, unsigned char *src,
> >  	struct NCR5380_hostdata *hostdata = shost_priv(instance);
> >  	int blocks = len / 128;
> >  	int start = 0;
> > -	int i;
> >  
> >  	NCR5380_write(hostdata->c400_ctl_status, CSR_BASE);
> >  	NCR5380_write(hostdata->c400_blk_cnt, blocks);
> > @@ -681,36 +676,16 @@ static inline int NCR5380_pwrite(struct Scsi_Host *instance, unsigned char *src,
> >  		blocks--;
> >  	}
> >  
> > -#if 0
> > -	printk("53C400w: waiting for registers to be available\n");
> > -	THEY NEVER DO ! while (NCR5380_read(hostdata->c400_ctl_status) & CSR_53C80_REG);
> > -	printk("53C400w: Got em\n");
> > -#endif
> > -
> > -	/* Let's wait for this instead - could be ugly */
> > -	/* All documentation says to check for this. Maybe my hardware is too
> > -	 * fast. Waiting for it seems to work fine! KLL
> > -	 */
> > -	while (!(i = NCR5380_read(hostdata->c400_ctl_status) & CSR_GATED_53C80_IRQ)) {
> > +	/* wait for 53C80 registers to be available */
> > +	while (!(NCR5380_read(hostdata->c400_ctl_status) & CSR_53C80_REG)) {
> >  		udelay(4); /* DTC436 chip hangs without this */
> 
> ... based on the above, this udelay is probably not needed.
> 
> (Or perhaps it is only needed once, in between the final host_buf register 
> access and the first ctl_status access??)

I guess that the delay is needed when the chip does write in the background.
But why only on the last block?
Adding delays inside the while(1) loop does not help, it crashes anyway.
Single delay before the first ctl_status does not help either (perhaps only
if it's long enough for the write to complete).

The chip also crashes in transfer_pio during bigger transfers in a similar
way. With Quantum HDD, it did not crash once I got PDMA working.
But with a faster IBM HDD, it crashes even with smaller PIO trasnfers.

> Is there any reference in the docs to timing sensitivity?

Haven't found anything in NCR docs. Unfortunately, we don't have any DTC
docs.

> >  		/* FIXME - no timeout */
> >  	}
> >  
> > -	/*
> > -	 * I know. i is certainly != 0 here but the loop is new. See previous
> > -	 * comment.
> > -	 */
> 
> Thanks for cleaning up this mess!
> 


-- 
Ondrej Zary

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

* Re: [PATCH v2 74/71] ncr5380: Enable PDMA for NCR53C400A
  2015-12-06 22:21 ` [PATCH v2 74/71] ncr5380: Enable PDMA for NCR53C400A Ondrej Zary
@ 2015-12-08  2:05   ` Finn Thain
  2015-12-09 13:39     ` Ondrej Zary
  0 siblings, 1 reply; 268+ messages in thread
From: Finn Thain @ 2015-12-08  2:05 UTC (permalink / raw)
  To: Ondrej Zary; +Cc: Michael Schmitz, linux-m68k, linux-scsi, linux-kernel


On Sun, 6 Dec 2015, Ondrej Zary wrote:

> Add I/O register mapping for NCR53C400A and enable PDMA mode to
> improve performance and fix non-working IRQ.
> 
> Tested with HP C2502 (and user-space enabler).
> 
> Signed-off-by: Ondrej Zary <linux@rainbow-software.org>
> ---
>  drivers/scsi/g_NCR5380.c |   14 +++++++++++---
>  1 file changed, 11 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/scsi/g_NCR5380.c b/drivers/scsi/g_NCR5380.c
> index 86740fd..099fdac 100644
> --- a/drivers/scsi/g_NCR5380.c
> +++ b/drivers/scsi/g_NCR5380.c
> @@ -324,7 +324,7 @@ static int __init generic_NCR5380_detect(struct scsi_host_template *tpnt)
>  #endif
>  			break;
>  		case BOARD_NCR53C400A:
> -			flags = FLAG_NO_PSEUDO_DMA;
> +			flags = FLAG_NO_DMA_FIXUP;
>  			ports = ncr_53c400a_ports;
>  			break;
>  		case BOARD_DTC3181E:
> @@ -406,11 +406,18 @@ static int __init generic_NCR5380_detect(struct scsi_host_template *tpnt)
>  		 * On NCR53C400 boards, NCR5380 registers are mapped 8 past
>  		 * the base address.
>  		 */
> -		if (overrides[current_override].board == BOARD_NCR53C400) {
> +		switch (overrides[current_override].board) {
> +		case BOARD_NCR53C400:
>  			instance->io_port += 8;
>  			hostdata->c400_ctl_status = 0;
>  			hostdata->c400_blk_cnt = 1;
>  			hostdata->c400_host_buf = 4;
> +			break;
> +		case BOARD_NCR53C400A:
> +			hostdata->c400_ctl_status = 9;
> +			hostdata->c400_blk_cnt = 10;
> +			hostdata->c400_host_buf = 8;
> +			break;
>  		}
>  #else
>  		instance->base = overrides[current_override].NCR5380_map_name;


For SCSI_G_NCR5380_MEM and BOARD_NCR53C400A (or BOARD_DTC3181E), you have 
not assigned c400_ctl_status, c400_blk_cnt and c400_host_buf. Perhaps we 
should throw an error, something like this?

 		hostdata->iomem = iomem;
-		if (overrides[current_override].board == BOARD_NCR53C400) {
+		switch (overrides[current_override].board) {
+		case BOARD_NCR53C400:
 			hostdata->c400_ctl_status = 0x100;
 			hostdata->c400_blk_cnt = 0x101;
 			hostdata->c400_host_buf = 0x104;
+			break;
+		case BOARD_NCR53C400A:
+			pr_err(DRV_MODULE_NAME ": unknown register offsets\n");
+			goto out_unregister;
 		}
 #endif
 
-- 

> @@ -425,7 +432,8 @@ static int __init generic_NCR5380_detect(struct scsi_host_template *tpnt)
>  		if (NCR5380_init(instance, flags))
>  			goto out_unregister;
>  
> -		if (overrides[current_override].board == BOARD_NCR53C400)
> +		if (overrides[current_override].board == BOARD_NCR53C400 ||
> +		    overrides[current_override].board == BOARD_NCR53C400A)
>  			NCR5380_write(hostdata->c400_ctl_status, CSR_BASE);
>  
>  		NCR5380_maybe_reset_bus(instance);
> 

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

* [PATCH v2 78/71] ncr5380: Add support for HP 53C400A-based cards (C2502)
  2015-11-18  8:34 ` Finn Thain
                   ` (87 preceding siblings ...)
  (?)
@ 2015-12-08  7:51 ` Ondrej Zary
  2015-12-08 11:40   ` Finn Thain
  -1 siblings, 1 reply; 268+ messages in thread
From: Ondrej Zary @ 2015-12-08  7:51 UTC (permalink / raw)
  To: Finn Thain, Michael Schmitz, linux-m68k, linux-scsi, linux-kernel

HP C2502 cards (based on 53C400A chips) use different magic numbers for
software-based I/O address configuration than other cards.
The configuration is also extended to allow setting the IRQ.

Move the configuration to a new function magic_configure() and move
magic the magic numbers into an array. Add new magic numbers for these
HP cards and hp_53c400a module parameter to use them.

Tested with HP C2502 and DTCT-436P.

Signed-off-by: Ondrej Zary <linux@rainbow-software.org>
---
 drivers/scsi/g_NCR5380.c |   76 ++++++++++++++++++++++++++++++++++++----------
 drivers/scsi/g_NCR5380.h |    1 +
 2 files changed, 61 insertions(+), 16 deletions(-)

diff --git a/drivers/scsi/g_NCR5380.c b/drivers/scsi/g_NCR5380.c
index 42fdeaf..121d143 100644
--- a/drivers/scsi/g_NCR5380.c
+++ b/drivers/scsi/g_NCR5380.c
@@ -80,6 +80,7 @@ static int ncr_5380;
 static int ncr_53c400;
 static int ncr_53c400a;
 static int dtc_3181e;
+static int hp_53c400a;
 
 static struct override {
 	NCR5380_map_type NCR5380_map_name;
@@ -225,6 +226,32 @@ static int __init do_DTC3181E_setup(char *str)
 
 #endif
 
+#ifndef SCSI_G_NCR5380_MEM
+/*
+ * Configure I/O address of 53C400A or DTC 3181 by writing magic numbers
+ * to ports 0x779 and 0x379. Two magic number sequences are known:
+ *  1. for generic NCR 53C400A-based cards and DTC436 chips
+ *  2. for HP C2502 card (also based on 53C400A but different decode logic)
+ */
+static void magic_configure(int idx, u8 irq, u8 magic[])
+{
+	u8 cfg = 0;
+
+	outb(magic[0], 0x779);
+	outb(magic[1], 0x379);
+	outb(magic[2], 0x379);
+	outb(magic[3], 0x379);
+	outb(magic[4], 0x379);
+
+	/* allowed IRQs for HP 53C400A */
+	if (irq != 2 && irq != 3 && irq != 4 && irq != 5 && irq != 7)
+		irq = 0;
+	if (idx >= 0 && idx <= 7)
+		cfg = 0x80 | idx | (irq << 4);
+	outb(cfg, 0x379);
+}
+#endif
+
 /**
  * 	generic_NCR5380_detect	-	look for NCR5380 controllers
  *	@tpnt: the scsi template
@@ -241,8 +268,9 @@ static int __init generic_NCR5380_detect(struct scsi_host_template *tpnt)
 	static int current_override;
 	int count;
 	unsigned int *ports;
+	u8 *magic;
 #ifndef SCSI_G_NCR5380_MEM
-	int i;
+	int i, port_idx;
 	unsigned long region_size = 16;
 #endif
 	static unsigned int __initdata ncr_53c400a_ports[] = {
@@ -251,6 +279,12 @@ static int __init generic_NCR5380_detect(struct scsi_host_template *tpnt)
 	static unsigned int __initdata dtc_3181e_ports[] = {
 		0x220, 0x240, 0x280, 0x2a0, 0x2c0, 0x300, 0x320, 0x340, 0
 	};
+	static u8 ncr_53c400a_magic[] __initdata = {	/* 53C400A & DTC 3181 */
+		0x59, 0xb9, 0xc5, 0xae, 0xa6
+	};
+	static u8 hp_53c400a_magic[] __initdata = {	/* HP C2502 */
+		0x0f, 0x22, 0xf0, 0x20, 0x80
+	};
 	int flags;
 	struct Scsi_Host *instance;
 	struct NCR5380_hostdata *hostdata;
@@ -273,6 +307,8 @@ static int __init generic_NCR5380_detect(struct scsi_host_template *tpnt)
 		overrides[0].board = BOARD_NCR53C400A;
 	else if (dtc_3181e)
 		overrides[0].board = BOARD_DTC3181E;
+	else if (hp_53c400a)
+		overrides[0].board = BOARD_HP53C400A;
 #ifndef SCSI_G_NCR5380_MEM
 	if (!current_override && isapnp_present()) {
 		struct pnp_dev *dev = NULL;
@@ -326,10 +362,17 @@ static int __init generic_NCR5380_detect(struct scsi_host_template *tpnt)
 		case BOARD_NCR53C400A:
 			flags = FLAG_NO_DMA_FIXUP;
 			ports = ncr_53c400a_ports;
+			magic = ncr_53c400a_magic;
+			break;
+		case BOARD_HP53C400A:
+			flags = FLAG_NO_DMA_FIXUP;
+			ports = ncr_53c400a_ports;
+			magic = hp_53c400a_magic;
 			break;
 		case BOARD_DTC3181E:
 			flags = FLAG_NO_DMA_FIXUP;
 			ports = dtc_3181e_ports;
+			magic = ncr_53c400a_magic;
 			break;
 		}
 
@@ -338,12 +381,7 @@ static int __init generic_NCR5380_detect(struct scsi_host_template *tpnt)
 			/* wakeup sequence for the NCR53C400A and DTC3181E */
 
 			/* Disable the adapter and look for a free io port */
-			outb(0x59, 0x779);
-			outb(0xb9, 0x379);
-			outb(0xc5, 0x379);
-			outb(0xae, 0x379);
-			outb(0xa6, 0x379);
-			outb(0x00, 0x379);
+			magic_configure(-1, 0, magic);
 
 			if (overrides[current_override].NCR5380_map_name != PORT_AUTO)
 				for (i = 0; ports[i]; i++) {
@@ -362,17 +400,14 @@ static int __init generic_NCR5380_detect(struct scsi_host_template *tpnt)
 				}
 			if (ports[i]) {
 				/* At this point we have our region reserved */
-				outb(0x59, 0x779);
-				outb(0xb9, 0x379);
-				outb(0xc5, 0x379);
-				outb(0xae, 0x379);
-				outb(0xa6, 0x379);
-				outb(0x80 | i, 0x379);	/* set io port to be used */
+				magic_configure(i, 0, magic); /* no IRQ yet */
 				outb(0xc0, ports[i] + 9);
-				if (inb(ports[i] + 9) != 0x80)
+				if (inb(ports[i] + 9) != 0x80) {
 					continue;
-				else
+				} else {
 					overrides[current_override].NCR5380_map_name = ports[i];
+					port_idx = i;
+				}
 			} else
 				continue;
 		}
@@ -418,6 +453,7 @@ static int __init generic_NCR5380_detect(struct scsi_host_template *tpnt)
 			hostdata->io_width = 2;	/* 16-bit PDMA */
 			/* fall through */
 		case BOARD_NCR53C400A:
+		case BOARD_HP53C400A:
 			hostdata->c400_ctl_status = 9;
 			hostdata->c400_blk_cnt = 10;
 			hostdata->c400_host_buf = 8;
@@ -438,6 +474,7 @@ static int __init generic_NCR5380_detect(struct scsi_host_template *tpnt)
 
 		if (overrides[current_override].board == BOARD_NCR53C400 ||
 		    overrides[current_override].board == BOARD_NCR53C400A ||
+		    overrides[current_override].board == BOARD_HP53C400A ||
 		    overrides[current_override].board == BOARD_DTC3181E)
 			NCR5380_write(hostdata->c400_ctl_status, CSR_BASE);
 
@@ -452,12 +489,18 @@ static int __init generic_NCR5380_detect(struct scsi_host_template *tpnt)
 		if (instance->irq == 255)
 			instance->irq = NO_IRQ;
 
-		if (instance->irq != NO_IRQ)
+		if (instance->irq != NO_IRQ) {
+#ifndef SCSI_G_NCR5380_MEM
+			/* set IRQ for HP 53C400A */
+			if (overrides[current_override].board == BOARD_HP53C400A)
+				magic_configure(port_idx, instance->irq, magic);
+#endif
 			if (request_irq(instance->irq, generic_NCR5380_intr,
 					0, "NCR5380", instance)) {
 				printk(KERN_WARNING "scsi%d : IRQ%d not free, interrupts disabled\n", instance->host_no, instance->irq);
 				instance->irq = NO_IRQ;
 			}
+		}
 
 		if (instance->irq == NO_IRQ) {
 			printk(KERN_INFO "scsi%d : interrupts not enabled. for better interactive performance,\n", instance->host_no);
@@ -743,6 +786,7 @@ module_param(ncr_5380, int, 0);
 module_param(ncr_53c400, int, 0);
 module_param(ncr_53c400a, int, 0);
 module_param(dtc_3181e, int, 0);
+module_param(hp_53c400a, int, 0);
 MODULE_LICENSE("GPL");
 
 #if !defined(SCSI_G_NCR5380_MEM) && defined(MODULE)
diff --git a/drivers/scsi/g_NCR5380.h b/drivers/scsi/g_NCR5380.h
index 5ab64d9..4fbae53 100644
--- a/drivers/scsi/g_NCR5380.h
+++ b/drivers/scsi/g_NCR5380.h
@@ -88,6 +88,7 @@
 #define BOARD_NCR53C400	1
 #define BOARD_NCR53C400A 2
 #define BOARD_DTC3181E	3
+#define BOARD_HP53C400A 4
 
 #endif /* GENERIC_NCR5380_H */
 
-- 
Ondrej Zary


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

* Re: [PATCH v2 78/71] ncr5380: Add support for HP 53C400A-based cards (C2502)
  2015-12-08  7:51 ` [PATCH v2 78/71] ncr5380: Add support for HP 53C400A-based cards (C2502) Ondrej Zary
@ 2015-12-08 11:40   ` Finn Thain
  2015-12-09 11:33     ` Ondrej Zary
  0 siblings, 1 reply; 268+ messages in thread
From: Finn Thain @ 2015-12-08 11:40 UTC (permalink / raw)
  To: Ondrej Zary; +Cc: Michael Schmitz, linux-m68k, linux-scsi, linux-kernel


On Tue, 8 Dec 2015, Ondrej Zary wrote:

> HP C2502 cards (based on 53C400A chips) use different magic numbers for 
> software-based I/O address configuration than other cards. The 
> configuration is also extended to allow setting the IRQ.
> 
> Move the configuration to a new function magic_configure() and move 
> magic the magic numbers into an array. Add new magic numbers for these 
> HP cards and hp_53c400a module parameter to use them.
> 
> Tested with HP C2502 and DTCT-436P.
> 
> Signed-off-by: Ondrej Zary <linux@rainbow-software.org>
> ---
>  drivers/scsi/g_NCR5380.c |   76 ++++++++++++++++++++++++++++++++++++----------
>  drivers/scsi/g_NCR5380.h |    1 +
>  2 files changed, 61 insertions(+), 16 deletions(-)
> 
> diff --git a/drivers/scsi/g_NCR5380.c b/drivers/scsi/g_NCR5380.c
> index 42fdeaf..121d143 100644
> --- a/drivers/scsi/g_NCR5380.c
> +++ b/drivers/scsi/g_NCR5380.c
> @@ -80,6 +80,7 @@ static int ncr_5380;
>  static int ncr_53c400;
>  static int ncr_53c400a;
>  static int dtc_3181e;
> +static int hp_53c400a;

>From the photos that I've seen, the HP cards have either NCR or SYMBIOS 
53C400A devices.

You've added a new setup option and a new board type, but the name you've 
chosen is neither the board type nor the device type. It is a combination.

>  
>  static struct override {
>  	NCR5380_map_type NCR5380_map_name;
> @@ -225,6 +226,32 @@ static int __init do_DTC3181E_setup(char *str)
>  
>  #endif
>  
> +#ifndef SCSI_G_NCR5380_MEM
> +/*
> + * Configure I/O address of 53C400A or DTC 3181 by writing magic numbers
> + * to ports 0x779 and 0x379. Two magic number sequences are known:
> + *  1. for generic NCR 53C400A-based cards and DTC436 chips
> + *  2. for HP C2502 card (also based on 53C400A but different decode logic)

Forgive my ignorance of ISA card design, but that suggests that these 
magic numbers are only relevant to HP C2502 boards and not SYM 53C400A 
devices in general (?) ...

> + */
> +static void magic_configure(int idx, u8 irq, u8 magic[])
> +{
> +	u8 cfg = 0;
> +
> +	outb(magic[0], 0x779);
> +	outb(magic[1], 0x379);
> +	outb(magic[2], 0x379);
> +	outb(magic[3], 0x379);
> +	outb(magic[4], 0x379);
> +
> +	/* allowed IRQs for HP 53C400A */
> +	if (irq != 2 && irq != 3 && irq != 4 && irq != 5 && irq != 7)
> +		irq = 0;
> +	if (idx >= 0 && idx <= 7)
> +		cfg = 0x80 | idx | (irq << 4);
> +	outb(cfg, 0x379);
> +}
> +#endif
> +
>  /**
>   * 	generic_NCR5380_detect	-	look for NCR5380 controllers
>   *	@tpnt: the scsi template
> @@ -241,8 +268,9 @@ static int __init generic_NCR5380_detect(struct scsi_host_template *tpnt)
>  	static int current_override;
>  	int count;
>  	unsigned int *ports;
> +	u8 *magic;
>  #ifndef SCSI_G_NCR5380_MEM
> -	int i;
> +	int i, port_idx;
>  	unsigned long region_size = 16;
>  #endif
>  	static unsigned int __initdata ncr_53c400a_ports[] = {
> @@ -251,6 +279,12 @@ static int __init generic_NCR5380_detect(struct scsi_host_template *tpnt)
>  	static unsigned int __initdata dtc_3181e_ports[] = {
>  		0x220, 0x240, 0x280, 0x2a0, 0x2c0, 0x300, 0x320, 0x340, 0
>  	};
> +	static u8 ncr_53c400a_magic[] __initdata = {	/* 53C400A & DTC 3181 */
> +		0x59, 0xb9, 0xc5, 0xae, 0xa6
> +	};
> +	static u8 hp_53c400a_magic[] __initdata = {	/* HP C2502 */
> +		0x0f, 0x22, 0xf0, 0x20, 0x80
> +	};

... so maybe that should be called 'hp_c2502_magic'?


>  	int flags;
>  	struct Scsi_Host *instance;
>  	struct NCR5380_hostdata *hostdata;
> @@ -273,6 +307,8 @@ static int __init generic_NCR5380_detect(struct scsi_host_template *tpnt)
>  		overrides[0].board = BOARD_NCR53C400A;
>  	else if (dtc_3181e)
>  		overrides[0].board = BOARD_DTC3181E;
> +	else if (hp_53c400a)
> +		overrides[0].board = BOARD_HP53C400A;
>  #ifndef SCSI_G_NCR5380_MEM
>  	if (!current_override && isapnp_present()) {
>  		struct pnp_dev *dev = NULL;
> @@ -326,10 +362,17 @@ static int __init generic_NCR5380_detect(struct scsi_host_template *tpnt)
>  		case BOARD_NCR53C400A:
>  			flags = FLAG_NO_DMA_FIXUP;
>  			ports = ncr_53c400a_ports;
> +			magic = ncr_53c400a_magic;
> +			break;
> +		case BOARD_HP53C400A:
> +			flags = FLAG_NO_DMA_FIXUP;
> +			ports = ncr_53c400a_ports;
> +			magic = hp_53c400a_magic;
>  			break;
>  		case BOARD_DTC3181E:
>  			flags = FLAG_NO_DMA_FIXUP;
>  			ports = dtc_3181e_ports;
> +			magic = ncr_53c400a_magic;
>  			break;
>  		}
>  
> @@ -338,12 +381,7 @@ static int __init generic_NCR5380_detect(struct scsi_host_template *tpnt)
>  			/* wakeup sequence for the NCR53C400A and DTC3181E */
>  
>  			/* Disable the adapter and look for a free io port */
> -			outb(0x59, 0x779);
> -			outb(0xb9, 0x379);
> -			outb(0xc5, 0x379);
> -			outb(0xae, 0x379);
> -			outb(0xa6, 0x379);
> -			outb(0x00, 0x379);
> +			magic_configure(-1, 0, magic);
>  
>  			if (overrides[current_override].NCR5380_map_name != PORT_AUTO)
>  				for (i = 0; ports[i]; i++) {
> @@ -362,17 +400,14 @@ static int __init generic_NCR5380_detect(struct scsi_host_template *tpnt)
>  				}
>  			if (ports[i]) {
>  				/* At this point we have our region reserved */
> -				outb(0x59, 0x779);
> -				outb(0xb9, 0x379);
> -				outb(0xc5, 0x379);
> -				outb(0xae, 0x379);
> -				outb(0xa6, 0x379);
> -				outb(0x80 | i, 0x379);	/* set io port to be used */
> +				magic_configure(i, 0, magic); /* no IRQ yet */
>  				outb(0xc0, ports[i] + 9);
> -				if (inb(ports[i] + 9) != 0x80)
> +				if (inb(ports[i] + 9) != 0x80) {
>  					continue;
> -				else
> +				} else {
>  					overrides[current_override].NCR5380_map_name = ports[i];
> +					port_idx = i;
> +				}
>  			} else
>  				continue;
>  		}
> @@ -418,6 +453,7 @@ static int __init generic_NCR5380_detect(struct scsi_host_template *tpnt)
>  			hostdata->io_width = 2;	/* 16-bit PDMA */
>  			/* fall through */
>  		case BOARD_NCR53C400A:
> +		case BOARD_HP53C400A:
>  			hostdata->c400_ctl_status = 9;
>  			hostdata->c400_blk_cnt = 10;
>  			hostdata->c400_host_buf = 8;
> @@ -438,6 +474,7 @@ static int __init generic_NCR5380_detect(struct scsi_host_template *tpnt)
>  
>  		if (overrides[current_override].board == BOARD_NCR53C400 ||
>  		    overrides[current_override].board == BOARD_NCR53C400A ||
> +		    overrides[current_override].board == BOARD_HP53C400A ||
>  		    overrides[current_override].board == BOARD_DTC3181E)
>  			NCR5380_write(hostdata->c400_ctl_status, CSR_BASE);
>  
> @@ -452,12 +489,18 @@ static int __init generic_NCR5380_detect(struct scsi_host_template *tpnt)
>  		if (instance->irq == 255)
>  			instance->irq = NO_IRQ;
>  
> -		if (instance->irq != NO_IRQ)
> +		if (instance->irq != NO_IRQ) {
> +#ifndef SCSI_G_NCR5380_MEM
> +			/* set IRQ for HP 53C400A */
> +			if (overrides[current_override].board == BOARD_HP53C400A)
> +				magic_configure(port_idx, instance->irq, magic);
> +#endif
>  			if (request_irq(instance->irq, generic_NCR5380_intr,
>  					0, "NCR5380", instance)) {
>  				printk(KERN_WARNING "scsi%d : IRQ%d not free, interrupts disabled\n", instance->host_no, instance->irq);
>  				instance->irq = NO_IRQ;
>  			}
> +		}
>  
>  		if (instance->irq == NO_IRQ) {
>  			printk(KERN_INFO "scsi%d : interrupts not enabled. for better interactive performance,\n", instance->host_no);
> @@ -743,6 +786,7 @@ module_param(ncr_5380, int, 0);
>  module_param(ncr_53c400, int, 0);
>  module_param(ncr_53c400a, int, 0);
>  module_param(dtc_3181e, int, 0);
> +module_param(hp_53c400a, int, 0);

Any reason you did not add the corresponding __setup option?

Did you consider re-using the existing ncr_53c400a option (for port & irq 
settings) and adding a new setup option and module param for card magic?

(I like orthogonal command line options. dtc_3181e doesn't really bother 
me because the dtc-436 device seems to correspond to the 3181e card and 
vice versa.)

>  MODULE_LICENSE("GPL");
>  
>  #if !defined(SCSI_G_NCR5380_MEM) && defined(MODULE)
> diff --git a/drivers/scsi/g_NCR5380.h b/drivers/scsi/g_NCR5380.h
> index 5ab64d9..4fbae53 100644
> --- a/drivers/scsi/g_NCR5380.h
> +++ b/drivers/scsi/g_NCR5380.h
> @@ -88,6 +88,7 @@
>  #define BOARD_NCR53C400	1
>  #define BOARD_NCR53C400A 2
>  #define BOARD_DTC3181E	3
> +#define BOARD_HP53C400A 4
>  
>  #endif /* GENERIC_NCR5380_H */
>  
> 

-- 

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

* Re: [PATCH v2 78/71] ncr5380: Add support for HP 53C400A-based cards (C2502)
  2015-12-08 11:40   ` Finn Thain
@ 2015-12-09 11:33     ` Ondrej Zary
  2015-12-10 23:38       ` Finn Thain
  0 siblings, 1 reply; 268+ messages in thread
From: Ondrej Zary @ 2015-12-09 11:33 UTC (permalink / raw)
  To: Finn Thain; +Cc: Michael Schmitz, linux-m68k, linux-scsi, linux-kernel

On Tuesday 08 December 2015 12:40:18 Finn Thain wrote:
> 
> On Tue, 8 Dec 2015, Ondrej Zary wrote:
> 
> > HP C2502 cards (based on 53C400A chips) use different magic numbers for 
> > software-based I/O address configuration than other cards. The 
> > configuration is also extended to allow setting the IRQ.
> > 
> > Move the configuration to a new function magic_configure() and move 
> > magic the magic numbers into an array. Add new magic numbers for these 
> > HP cards and hp_53c400a module parameter to use them.
> > 
> > Tested with HP C2502 and DTCT-436P.
> > 
> > Signed-off-by: Ondrej Zary <linux@rainbow-software.org>
> > ---
> >  drivers/scsi/g_NCR5380.c |   76 ++++++++++++++++++++++++++++++++++++----------
> >  drivers/scsi/g_NCR5380.h |    1 +
> >  2 files changed, 61 insertions(+), 16 deletions(-)
> > 
> > diff --git a/drivers/scsi/g_NCR5380.c b/drivers/scsi/g_NCR5380.c
> > index 42fdeaf..121d143 100644
> > --- a/drivers/scsi/g_NCR5380.c
> > +++ b/drivers/scsi/g_NCR5380.c
> > @@ -80,6 +80,7 @@ static int ncr_5380;
> >  static int ncr_53c400;
> >  static int ncr_53c400a;
> >  static int dtc_3181e;
> > +static int hp_53c400a;
> 
> From the photos that I've seen, the HP cards have either NCR or SYMBIOS 
> 53C400A devices.
> 
> You've added a new setup option and a new board type, but the name you've 
> chosen is neither the board type nor the device type. It is a combination.

Because it's a HP board with NCR/SYMBIOS 53C400A chip. Windows driver calls
it "Symbios Logic 53C400A (HP Version)", suggesting that there might be more
compatible cards.
But search did not found any on the web, only C2502. So I'll rename it to
hp_c2502.

> >  
> >  static struct override {
> >  	NCR5380_map_type NCR5380_map_name;
> > @@ -225,6 +226,32 @@ static int __init do_DTC3181E_setup(char *str)
> >  
> >  #endif
> >  
> > +#ifndef SCSI_G_NCR5380_MEM
> > +/*
> > + * Configure I/O address of 53C400A or DTC 3181 by writing magic numbers
> > + * to ports 0x779 and 0x379. Two magic number sequences are known:
> > + *  1. for generic NCR 53C400A-based cards and DTC436 chips
> > + *  2. for HP C2502 card (also based on 53C400A but different decode logic)
> 
> Forgive my ignorance of ISA card design, but that suggests that these 
> magic numbers are only relevant to HP C2502 boards and not SYM 53C400A 
> devices in general (?) ...

Looks like the original magic numbers (they came from the outb() calls, now
in ncr_53c400a_magic[]) are hardcoded in the 53C400A chip (and also DTC
chips).

HP C2502 card has some PALCE chips between the ISA bus and 53C400A. They
probably react to the HP-specific magic numbers (and don't pass the
"original" magic numbers to the 53C400A chip).

> > + */
> > +static void magic_configure(int idx, u8 irq, u8 magic[])
> > +{
> > +	u8 cfg = 0;
> > +
> > +	outb(magic[0], 0x779);
> > +	outb(magic[1], 0x379);
> > +	outb(magic[2], 0x379);
> > +	outb(magic[3], 0x379);
> > +	outb(magic[4], 0x379);
> > +
> > +	/* allowed IRQs for HP 53C400A */
> > +	if (irq != 2 && irq != 3 && irq != 4 && irq != 5 && irq != 7)
> > +		irq = 0;
> > +	if (idx >= 0 && idx <= 7)
> > +		cfg = 0x80 | idx | (irq << 4);
> > +	outb(cfg, 0x379);
> > +}
> > +#endif
> > +
> >  /**
> >   * 	generic_NCR5380_detect	-	look for NCR5380 controllers
> >   *	@tpnt: the scsi template
> > @@ -241,8 +268,9 @@ static int __init generic_NCR5380_detect(struct scsi_host_template *tpnt)
> >  	static int current_override;
> >  	int count;
> >  	unsigned int *ports;
> > +	u8 *magic;
> >  #ifndef SCSI_G_NCR5380_MEM
> > -	int i;
> > +	int i, port_idx;
> >  	unsigned long region_size = 16;
> >  #endif
> >  	static unsigned int __initdata ncr_53c400a_ports[] = {
> > @@ -251,6 +279,12 @@ static int __init generic_NCR5380_detect(struct scsi_host_template *tpnt)
> >  	static unsigned int __initdata dtc_3181e_ports[] = {
> >  		0x220, 0x240, 0x280, 0x2a0, 0x2c0, 0x300, 0x320, 0x340, 0
> >  	};
> > +	static u8 ncr_53c400a_magic[] __initdata = {	/* 53C400A & DTC 3181 */
> > +		0x59, 0xb9, 0xc5, 0xae, 0xa6
> > +	};
> > +	static u8 hp_53c400a_magic[] __initdata = {	/* HP C2502 */
> > +		0x0f, 0x22, 0xf0, 0x20, 0x80
> > +	};
> 
> ... so maybe that should be called 'hp_c2502_magic'?

Yes.

> >  	int flags;
> >  	struct Scsi_Host *instance;
> >  	struct NCR5380_hostdata *hostdata;
> > @@ -273,6 +307,8 @@ static int __init generic_NCR5380_detect(struct scsi_host_template *tpnt)
> >  		overrides[0].board = BOARD_NCR53C400A;
> >  	else if (dtc_3181e)
> >  		overrides[0].board = BOARD_DTC3181E;
> > +	else if (hp_53c400a)
> > +		overrides[0].board = BOARD_HP53C400A;
> >  #ifndef SCSI_G_NCR5380_MEM
> >  	if (!current_override && isapnp_present()) {
> >  		struct pnp_dev *dev = NULL;
> > @@ -326,10 +362,17 @@ static int __init generic_NCR5380_detect(struct scsi_host_template *tpnt)
> >  		case BOARD_NCR53C400A:
> >  			flags = FLAG_NO_DMA_FIXUP;
> >  			ports = ncr_53c400a_ports;
> > +			magic = ncr_53c400a_magic;
> > +			break;
> > +		case BOARD_HP53C400A:
> > +			flags = FLAG_NO_DMA_FIXUP;
> > +			ports = ncr_53c400a_ports;
> > +			magic = hp_53c400a_magic;
> >  			break;
> >  		case BOARD_DTC3181E:
> >  			flags = FLAG_NO_DMA_FIXUP;
> >  			ports = dtc_3181e_ports;
> > +			magic = ncr_53c400a_magic;
> >  			break;
> >  		}
> >  
> > @@ -338,12 +381,7 @@ static int __init generic_NCR5380_detect(struct scsi_host_template *tpnt)
> >  			/* wakeup sequence for the NCR53C400A and DTC3181E */
> >  
> >  			/* Disable the adapter and look for a free io port */
> > -			outb(0x59, 0x779);
> > -			outb(0xb9, 0x379);
> > -			outb(0xc5, 0x379);
> > -			outb(0xae, 0x379);
> > -			outb(0xa6, 0x379);
> > -			outb(0x00, 0x379);

Magic numbers from here were moved to ncr_53c400a_magic[].

> > +			magic_configure(-1, 0, magic);
> >  
> >  			if (overrides[current_override].NCR5380_map_name != PORT_AUTO)
> >  				for (i = 0; ports[i]; i++) {
> > @@ -362,17 +400,14 @@ static int __init generic_NCR5380_detect(struct scsi_host_template *tpnt)
> >  				}
> >  			if (ports[i]) {
> >  				/* At this point we have our region reserved */
> > -				outb(0x59, 0x779);
> > -				outb(0xb9, 0x379);
> > -				outb(0xc5, 0x379);
> > -				outb(0xae, 0x379);
> > -				outb(0xa6, 0x379);
> > -				outb(0x80 | i, 0x379);	/* set io port to be used */
> > +				magic_configure(i, 0, magic); /* no IRQ yet */
> >  				outb(0xc0, ports[i] + 9);
> > -				if (inb(ports[i] + 9) != 0x80)
> > +				if (inb(ports[i] + 9) != 0x80) {
> >  					continue;
> > -				else
> > +				} else {
> >  					overrides[current_override].NCR5380_map_name = ports[i];
> > +					port_idx = i;
> > +				}
> >  			} else
> >  				continue;
> >  		}
> > @@ -418,6 +453,7 @@ static int __init generic_NCR5380_detect(struct scsi_host_template *tpnt)
> >  			hostdata->io_width = 2;	/* 16-bit PDMA */
> >  			/* fall through */
> >  		case BOARD_NCR53C400A:
> > +		case BOARD_HP53C400A:
> >  			hostdata->c400_ctl_status = 9;
> >  			hostdata->c400_blk_cnt = 10;
> >  			hostdata->c400_host_buf = 8;
> > @@ -438,6 +474,7 @@ static int __init generic_NCR5380_detect(struct scsi_host_template *tpnt)
> >  
> >  		if (overrides[current_override].board == BOARD_NCR53C400 ||
> >  		    overrides[current_override].board == BOARD_NCR53C400A ||
> > +		    overrides[current_override].board == BOARD_HP53C400A ||
> >  		    overrides[current_override].board == BOARD_DTC3181E)
> >  			NCR5380_write(hostdata->c400_ctl_status, CSR_BASE);
> >  
> > @@ -452,12 +489,18 @@ static int __init generic_NCR5380_detect(struct scsi_host_template *tpnt)
> >  		if (instance->irq == 255)
> >  			instance->irq = NO_IRQ;
> >  
> > -		if (instance->irq != NO_IRQ)
> > +		if (instance->irq != NO_IRQ) {
> > +#ifndef SCSI_G_NCR5380_MEM
> > +			/* set IRQ for HP 53C400A */
> > +			if (overrides[current_override].board == BOARD_HP53C400A)
> > +				magic_configure(port_idx, instance->irq, magic);
> > +#endif
> >  			if (request_irq(instance->irq, generic_NCR5380_intr,
> >  					0, "NCR5380", instance)) {
> >  				printk(KERN_WARNING "scsi%d : IRQ%d not free, interrupts disabled\n", instance->host_no, instance->irq);
> >  				instance->irq = NO_IRQ;
> >  			}
> > +		}
> >  
> >  		if (instance->irq == NO_IRQ) {
> >  			printk(KERN_INFO "scsi%d : interrupts not enabled. for better interactive performance,\n", instance->host_no);
> > @@ -743,6 +786,7 @@ module_param(ncr_5380, int, 0);
> >  module_param(ncr_53c400, int, 0);
> >  module_param(ncr_53c400a, int, 0);
> >  module_param(dtc_3181e, int, 0);
> > +module_param(hp_53c400a, int, 0);
> 
> Any reason you did not add the corresponding __setup option?

I wonder if __setup is really required. I thought that it should go away and
module parameters used instead.

> Did you consider re-using the existing ncr_53c400a option (for port & irq 
> settings) and adding a new setup option and module param for card magic?

Looks like a good idea.

> (I like orthogonal command line options. dtc_3181e doesn't really bother 
> me because the dtc-436 device seems to correspond to the 3181e card and 
> vice versa.)
> 
> >  MODULE_LICENSE("GPL");
> >  
> >  #if !defined(SCSI_G_NCR5380_MEM) && defined(MODULE)
> > diff --git a/drivers/scsi/g_NCR5380.h b/drivers/scsi/g_NCR5380.h
> > index 5ab64d9..4fbae53 100644
> > --- a/drivers/scsi/g_NCR5380.h
> > +++ b/drivers/scsi/g_NCR5380.h
> > @@ -88,6 +88,7 @@
> >  #define BOARD_NCR53C400	1
> >  #define BOARD_NCR53C400A 2
> >  #define BOARD_DTC3181E	3
> > +#define BOARD_HP53C400A 4
> >  
> >  #endif /* GENERIC_NCR5380_H */
> >  
> > 
> 


-- 
Ondrej Zary

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

* [PATCH v3 78/71] ncr5380: Add support for HP 53C400A-based cards (C2502)
  2015-11-18  8:34 ` Finn Thain
                   ` (88 preceding siblings ...)
  (?)
@ 2015-12-09 12:11 ` Ondrej Zary
  -1 siblings, 0 replies; 268+ messages in thread
From: Ondrej Zary @ 2015-12-09 12:11 UTC (permalink / raw)
  To: Finn Thain, Michael Schmitz, linux-m68k, linux-scsi, linux-kernel

HP C2502 cards (based on 53C400A chips) use different magic numbers for
software-based I/O address configuration than other cards.
The configuration is also extended to allow setting the IRQ.

Move the configuration to a new function magic_configure() and move
magic the magic numbers into an array. Add new magic numbers for these
HP cards and hp_c2502 module parameter to use them, e.g.:
modprobe g_NCR5380 ncr_irq=7 ncr_addr=0x280 ncr_53c400a=1 hp_c2502=1

Tested with HP C2502 and DTCT-436P.

Signed-off-by: Ondrej Zary <linux@rainbow-software.org>
---
 drivers/scsi/g_NCR5380.c |   74 ++++++++++++++++++++++++++++++++++++----------
 1 file changed, 58 insertions(+), 16 deletions(-)

diff --git a/drivers/scsi/g_NCR5380.c b/drivers/scsi/g_NCR5380.c
index 42fdeaf..dd32c68 100644
--- a/drivers/scsi/g_NCR5380.c
+++ b/drivers/scsi/g_NCR5380.c
@@ -80,12 +80,14 @@ static int ncr_5380;
 static int ncr_53c400;
 static int ncr_53c400a;
 static int dtc_3181e;
+static int hp_c2502;
 
 static struct override {
 	NCR5380_map_type NCR5380_map_name;
 	int irq;
 	int dma;
 	int board;		/* Use NCR53c400, Ricoh, etc. extensions ? */
+	bool hp_c2502;
 } overrides
 #ifdef GENERIC_NCR5380_OVERRIDE
 [] __initdata = GENERIC_NCR5380_OVERRIDE;
@@ -225,6 +227,32 @@ static int __init do_DTC3181E_setup(char *str)
 
 #endif
 
+#ifndef SCSI_G_NCR5380_MEM
+/*
+ * Configure I/O address of 53C400A or DTC436 by writing magic numbers
+ * to ports 0x779 and 0x379. Two magic number sequences are known:
+ *  1. for generic NCR 53C400A-based cards and DTC436 chips
+ *  2. for HP C2502 card (also based on 53C400A but different decode logic)
+ */
+static void magic_configure(int idx, u8 irq, u8 magic[])
+{
+	u8 cfg = 0;
+
+	outb(magic[0], 0x779);
+	outb(magic[1], 0x379);
+	outb(magic[2], 0x379);
+	outb(magic[3], 0x379);
+	outb(magic[4], 0x379);
+
+	/* allowed IRQs for HP 53C400A */
+	if (irq != 2 && irq != 3 && irq != 4 && irq != 5 && irq != 7)
+		irq = 0;
+	if (idx >= 0 && idx <= 7)
+		cfg = 0x80 | idx | (irq << 4);
+	outb(cfg, 0x379);
+}
+#endif
+
 /**
  * 	generic_NCR5380_detect	-	look for NCR5380 controllers
  *	@tpnt: the scsi template
@@ -241,8 +269,9 @@ static int __init generic_NCR5380_detect(struct scsi_host_template *tpnt)
 	static int current_override;
 	int count;
 	unsigned int *ports;
+	u8 *magic;
 #ifndef SCSI_G_NCR5380_MEM
-	int i;
+	int i, port_idx;
 	unsigned long region_size = 16;
 #endif
 	static unsigned int __initdata ncr_53c400a_ports[] = {
@@ -251,6 +280,12 @@ static int __init generic_NCR5380_detect(struct scsi_host_template *tpnt)
 	static unsigned int __initdata dtc_3181e_ports[] = {
 		0x220, 0x240, 0x280, 0x2a0, 0x2c0, 0x300, 0x320, 0x340, 0
 	};
+	static u8 ncr_53c400a_magic[] __initdata = {	/* 53C400A & DTC436 */
+		0x59, 0xb9, 0xc5, 0xae, 0xa6
+	};
+	static u8 hp_c2502_magic[] __initdata = {	/* HP C2502 */
+		0x0f, 0x22, 0xf0, 0x20, 0x80
+	};
 	int flags;
 	struct Scsi_Host *instance;
 	struct NCR5380_hostdata *hostdata;
@@ -273,6 +308,8 @@ static int __init generic_NCR5380_detect(struct scsi_host_template *tpnt)
 		overrides[0].board = BOARD_NCR53C400A;
 	else if (dtc_3181e)
 		overrides[0].board = BOARD_DTC3181E;
+	if (hp_c2502)
+		overrides[0].hp_c2502 = true;
 #ifndef SCSI_G_NCR5380_MEM
 	if (!current_override && isapnp_present()) {
 		struct pnp_dev *dev = NULL;
@@ -326,24 +363,25 @@ static int __init generic_NCR5380_detect(struct scsi_host_template *tpnt)
 		case BOARD_NCR53C400A:
 			flags = FLAG_NO_DMA_FIXUP;
 			ports = ncr_53c400a_ports;
+			magic = ncr_53c400a_magic;
 			break;
 		case BOARD_DTC3181E:
 			flags = FLAG_NO_DMA_FIXUP;
 			ports = dtc_3181e_ports;
+			magic = ncr_53c400a_magic;
 			break;
 		}
+		if (overrides[current_override].hp_c2502)
+			magic = hp_c2502_magic;
+		else
+			magic = ncr_53c400a_magic;
 
 #ifndef SCSI_G_NCR5380_MEM
 		if (ports) {
 			/* wakeup sequence for the NCR53C400A and DTC3181E */
 
 			/* Disable the adapter and look for a free io port */
-			outb(0x59, 0x779);
-			outb(0xb9, 0x379);
-			outb(0xc5, 0x379);
-			outb(0xae, 0x379);
-			outb(0xa6, 0x379);
-			outb(0x00, 0x379);
+			magic_configure(-1, 0, magic);
 
 			if (overrides[current_override].NCR5380_map_name != PORT_AUTO)
 				for (i = 0; ports[i]; i++) {
@@ -362,17 +400,14 @@ static int __init generic_NCR5380_detect(struct scsi_host_template *tpnt)
 				}
 			if (ports[i]) {
 				/* At this point we have our region reserved */
-				outb(0x59, 0x779);
-				outb(0xb9, 0x379);
-				outb(0xc5, 0x379);
-				outb(0xae, 0x379);
-				outb(0xa6, 0x379);
-				outb(0x80 | i, 0x379);	/* set io port to be used */
+				magic_configure(i, 0, magic); /* no IRQ yet */
 				outb(0xc0, ports[i] + 9);
-				if (inb(ports[i] + 9) != 0x80)
+				if (inb(ports[i] + 9) != 0x80) {
 					continue;
-				else
+				} else {
 					overrides[current_override].NCR5380_map_name = ports[i];
+					port_idx = i;
+				}
 			} else
 				continue;
 		}
@@ -452,12 +487,18 @@ static int __init generic_NCR5380_detect(struct scsi_host_template *tpnt)
 		if (instance->irq == 255)
 			instance->irq = NO_IRQ;
 
-		if (instance->irq != NO_IRQ)
+		if (instance->irq != NO_IRQ) {
+#ifndef SCSI_G_NCR5380_MEM
+			/* set IRQ for HP C2502 */
+			if (magic == hp_c2502_magic)
+				magic_configure(port_idx, instance->irq, magic);
+#endif
 			if (request_irq(instance->irq, generic_NCR5380_intr,
 					0, "NCR5380", instance)) {
 				printk(KERN_WARNING "scsi%d : IRQ%d not free, interrupts disabled\n", instance->host_no, instance->irq);
 				instance->irq = NO_IRQ;
 			}
+		}
 
 		if (instance->irq == NO_IRQ) {
 			printk(KERN_INFO "scsi%d : interrupts not enabled. for better interactive performance,\n", instance->host_no);
@@ -743,6 +784,7 @@ module_param(ncr_5380, int, 0);
 module_param(ncr_53c400, int, 0);
 module_param(ncr_53c400a, int, 0);
 module_param(dtc_3181e, int, 0);
+module_param(hp_c2502, int, 0);
 MODULE_LICENSE("GPL");
 
 #if !defined(SCSI_G_NCR5380_MEM) && defined(MODULE)
-- 
Ondrej Zary


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

* Re: [PATCH v2 74/71] ncr5380: Enable PDMA for NCR53C400A
  2015-12-08  2:05   ` Finn Thain
@ 2015-12-09 13:39     ` Ondrej Zary
  2015-12-10 23:39       ` Finn Thain
  0 siblings, 1 reply; 268+ messages in thread
From: Ondrej Zary @ 2015-12-09 13:39 UTC (permalink / raw)
  To: Finn Thain; +Cc: Michael Schmitz, linux-m68k, linux-scsi, linux-kernel

On Tuesday 08 December 2015 03:05:11 Finn Thain wrote:
> 
> On Sun, 6 Dec 2015, Ondrej Zary wrote:
> 
> > Add I/O register mapping for NCR53C400A and enable PDMA mode to
> > improve performance and fix non-working IRQ.
> > 
> > Tested with HP C2502 (and user-space enabler).
> > 
> > Signed-off-by: Ondrej Zary <linux@rainbow-software.org>
> > ---
> >  drivers/scsi/g_NCR5380.c |   14 +++++++++++---
> >  1 file changed, 11 insertions(+), 3 deletions(-)
> > 
> > diff --git a/drivers/scsi/g_NCR5380.c b/drivers/scsi/g_NCR5380.c
> > index 86740fd..099fdac 100644
> > --- a/drivers/scsi/g_NCR5380.c
> > +++ b/drivers/scsi/g_NCR5380.c
> > @@ -324,7 +324,7 @@ static int __init generic_NCR5380_detect(struct scsi_host_template *tpnt)
> >  #endif
> >  			break;
> >  		case BOARD_NCR53C400A:
> > -			flags = FLAG_NO_PSEUDO_DMA;
> > +			flags = FLAG_NO_DMA_FIXUP;
> >  			ports = ncr_53c400a_ports;
> >  			break;
> >  		case BOARD_DTC3181E:
> > @@ -406,11 +406,18 @@ static int __init generic_NCR5380_detect(struct scsi_host_template *tpnt)
> >  		 * On NCR53C400 boards, NCR5380 registers are mapped 8 past
> >  		 * the base address.
> >  		 */
> > -		if (overrides[current_override].board == BOARD_NCR53C400) {
> > +		switch (overrides[current_override].board) {
> > +		case BOARD_NCR53C400:
> >  			instance->io_port += 8;
> >  			hostdata->c400_ctl_status = 0;
> >  			hostdata->c400_blk_cnt = 1;
> >  			hostdata->c400_host_buf = 4;
> > +			break;
> > +		case BOARD_NCR53C400A:
> > +			hostdata->c400_ctl_status = 9;
> > +			hostdata->c400_blk_cnt = 10;
> > +			hostdata->c400_host_buf = 8;
> > +			break;
> >  		}
> >  #else
> >  		instance->base = overrides[current_override].NCR5380_map_name;
> 
> 
> For SCSI_G_NCR5380_MEM and BOARD_NCR53C400A (or BOARD_DTC3181E), you have 
> not assigned c400_ctl_status, c400_blk_cnt and c400_host_buf. Perhaps we 
> should throw an error, something like this?
> 
>  		hostdata->iomem = iomem;
> -		if (overrides[current_override].board == BOARD_NCR53C400) {
> +		switch (overrides[current_override].board) {
> +		case BOARD_NCR53C400:
>  			hostdata->c400_ctl_status = 0x100;
>  			hostdata->c400_blk_cnt = 0x101;
>  			hostdata->c400_host_buf = 0x104;
> +			break;
> +		case BOARD_NCR53C400A:
> +			pr_err(DRV_MODULE_NAME ": unknown register offsets\n");
> +			goto out_unregister;
>  		}
>  #endif

We don't need to fail, just disable PDMA by setting:
flags = FLAG_NO_PSEUDO_DMA;

And BTW. this:
                if (overrides[current_override].board == BOARD_NCR53C400 ||
                    overrides[current_override].board == BOARD_NCR53C400A)
                        NCR5380_write(hostdata->c400_ctl_status, CSR_BASE);

should then be, solving the problem of growing if condition:
		if (!(flags & FLAG_NO_PSEUDO_DMA))
                        NCR5380_write(hostdata->c400_ctl_status, CSR_BASE);

-- 
Ondrej Zary

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

* Re: [PATCH v2 78/71] ncr5380: Add support for HP 53C400A-based cards (C2502)
  2015-12-09 11:33     ` Ondrej Zary
@ 2015-12-10 23:38       ` Finn Thain
  0 siblings, 0 replies; 268+ messages in thread
From: Finn Thain @ 2015-12-10 23:38 UTC (permalink / raw)
  To: Ondrej Zary; +Cc: Michael Schmitz, linux-m68k, linux-scsi, linux-kernel


On Wed, 9 Dec 2015, Ondrej Zary wrote:

> > > @@ -743,6 +786,7 @@ module_param(ncr_5380, int, 0);
> > >  module_param(ncr_53c400, int, 0);
> > >  module_param(ncr_53c400a, int, 0);
> > >  module_param(dtc_3181e, int, 0);
> > > +module_param(hp_53c400a, int, 0);
> > 
> > Any reason you did not add the corresponding __setup option?
> 
> I wonder if __setup is really required. I thought that it should go away 
> and module parameters used instead.

Yes, after re-reading the header files I see that you are right.

> 
> > Did you consider re-using the existing ncr_53c400a option (for port & 
> > irq settings) and adding a new setup option and module param for card 
> > magic?
> 
> Looks like a good idea.

What I had in mind was an 'ncr_magic' option, to go with 'ncr_irq' and 
'ncr_addr'. This is supposed to be a generic driver, after all.

But now that I've seen what that would involve (adding another member to 
struct override) I've changed my mind.

I think the new board type was the right approach. That is, a combination 
of your v2 and v3 patches. I'll send my version to you to test.

Thanks.

-- 

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

* Re: [PATCH v2 74/71] ncr5380: Enable PDMA for NCR53C400A
  2015-12-09 13:39     ` Ondrej Zary
@ 2015-12-10 23:39       ` Finn Thain
  0 siblings, 0 replies; 268+ messages in thread
From: Finn Thain @ 2015-12-10 23:39 UTC (permalink / raw)
  To: Ondrej Zary; +Cc: Michael Schmitz, linux-m68k, linux-scsi, linux-kernel


On Wed, 9 Dec 2015, Ondrej Zary wrote:

> On Tuesday 08 December 2015 03:05:11 Finn Thain wrote:
> > 
> > On Sun, 6 Dec 2015, Ondrej Zary wrote:
> > 
> > > Add I/O register mapping for NCR53C400A and enable PDMA mode to
> > > improve performance and fix non-working IRQ.
> > > 
> > > Tested with HP C2502 (and user-space enabler).
> > > 
> > > Signed-off-by: Ondrej Zary <linux@rainbow-software.org>
> > > ---
> > >  drivers/scsi/g_NCR5380.c |   14 +++++++++++---
> > >  1 file changed, 11 insertions(+), 3 deletions(-)
> > > 
> > > diff --git a/drivers/scsi/g_NCR5380.c b/drivers/scsi/g_NCR5380.c
> > > index 86740fd..099fdac 100644
> > > --- a/drivers/scsi/g_NCR5380.c
> > > +++ b/drivers/scsi/g_NCR5380.c
> > > @@ -324,7 +324,7 @@ static int __init generic_NCR5380_detect(struct scsi_host_template *tpnt)
> > >  #endif
> > >  			break;
> > >  		case BOARD_NCR53C400A:
> > > -			flags = FLAG_NO_PSEUDO_DMA;
> > > +			flags = FLAG_NO_DMA_FIXUP;
> > >  			ports = ncr_53c400a_ports;
> > >  			break;
> > >  		case BOARD_DTC3181E:
> > > @@ -406,11 +406,18 @@ static int __init generic_NCR5380_detect(struct scsi_host_template *tpnt)
> > >  		 * On NCR53C400 boards, NCR5380 registers are mapped 8 past
> > >  		 * the base address.
> > >  		 */
> > > -		if (overrides[current_override].board == BOARD_NCR53C400) {
> > > +		switch (overrides[current_override].board) {
> > > +		case BOARD_NCR53C400:
> > >  			instance->io_port += 8;
> > >  			hostdata->c400_ctl_status = 0;
> > >  			hostdata->c400_blk_cnt = 1;
> > >  			hostdata->c400_host_buf = 4;
> > > +			break;
> > > +		case BOARD_NCR53C400A:
> > > +			hostdata->c400_ctl_status = 9;
> > > +			hostdata->c400_blk_cnt = 10;
> > > +			hostdata->c400_host_buf = 8;
> > > +			break;
> > >  		}
> > >  #else
> > >  		instance->base = overrides[current_override].NCR5380_map_name;
> > 
> > 
> > For SCSI_G_NCR5380_MEM and BOARD_NCR53C400A (or BOARD_DTC3181E), you have 
> > not assigned c400_ctl_status, c400_blk_cnt and c400_host_buf. Perhaps we 
> > should throw an error, something like this?
> > 
> >  		hostdata->iomem = iomem;
> > -		if (overrides[current_override].board == BOARD_NCR53C400) {
> > +		switch (overrides[current_override].board) {
> > +		case BOARD_NCR53C400:
> >  			hostdata->c400_ctl_status = 0x100;
> >  			hostdata->c400_blk_cnt = 0x101;
> >  			hostdata->c400_host_buf = 0x104;
> > +			break;
> > +		case BOARD_NCR53C400A:
> > +			pr_err(DRV_MODULE_NAME ": unknown register offsets\n");
> > +			goto out_unregister;
> >  		}
> >  #endif
> 
> We don't need to fail, just disable PDMA by setting:
> flags = FLAG_NO_PSEUDO_DMA;
> 
> And BTW. this:
>                 if (overrides[current_override].board == BOARD_NCR53C400 ||
>                     overrides[current_override].board == BOARD_NCR53C400A)
>                         NCR5380_write(hostdata->c400_ctl_status, CSR_BASE);
> 
> should then be, solving the problem of growing if condition:
> 		if (!(flags & FLAG_NO_PSEUDO_DMA))
>                         NCR5380_write(hostdata->c400_ctl_status, CSR_BASE);
> 

We already resolved that problem. Julian Calaby and I agreed that a switch 
statement is better than a flag here.

Moreover, if the user sets the 'ncr_53c400' or 'ncr_53c400a' module 
options I presume they expect corresponding device initialization. I don't 
think PIO means we should skip that.

Passing 'ncr_53c400' or 'ncr_53c400a' options to the g_NCR5380_mmio module 
has to give an error if we don't have enough information about the board 
to allow us to do the right thing.

(Passing the 'ncr_5380' module param may give the result you wanted.)

BTW, I fixed up this patch when I added it to my queue. I'll send you my 
version to test.

Thanks.

-- 

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

end of thread, other threads:[~2015-12-10 23:39 UTC | newest]

Thread overview: 268+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-11-18  8:34 [PATCH 00/71] More fixes, cleanup and modernization for NCR5380 drivers Finn Thain
2015-11-18  8:34 ` Finn Thain
2015-11-18  8:34 ` [PATCH 01/71] atari_scsi: Fix SCSI host ID setting Finn Thain
2015-11-18  8:34   ` Finn Thain
2015-11-19  7:37   ` Hannes Reinecke
2015-11-18  8:34 ` [PATCH 02/71] ncr5380: Remove redundant static variable initializers Finn Thain
2015-11-18  8:34   ` Finn Thain
2015-11-19  7:37   ` Hannes Reinecke
2015-11-18  8:34 ` [PATCH 03/71] ncr5380: Eliminate PDEBUG*, TDEBUG* and DTCDEBUG* macros Finn Thain
2015-11-18  8:34   ` Finn Thain
2015-11-19  7:38   ` Hannes Reinecke
2015-11-18  8:34 ` [PATCH 04/71] ncr5380: Remove more pointless macros Finn Thain
2015-11-18  8:34   ` Finn Thain
2015-11-19  7:38   ` Hannes Reinecke
2015-11-18  8:35 ` [PATCH 05/71] ncr5380: Remove NCR5380_local_declare and NCR5380_setup macros Finn Thain
2015-11-18  8:35   ` Finn Thain
2015-11-18  8:35   ` Finn Thain
2015-11-19  7:41   ` Hannes Reinecke
2015-11-19  7:41     ` Hannes Reinecke
2015-11-18  8:35 ` [PATCH 06/71] ncr5380: Remove NCR5380_instance_name macro Finn Thain
2015-11-18  8:35   ` Finn Thain
2015-11-19  7:41   ` Hannes Reinecke
2015-11-18  8:35 ` [PATCH 07/71] ncr5380: Split NCR5380_init() into two functions Finn Thain
2015-11-18  8:35   ` Finn Thain
2015-11-18  8:35   ` Finn Thain
2015-11-19 13:30   ` Hannes Reinecke
2015-11-19 13:30     ` Hannes Reinecke
2015-11-18  8:35 ` [PATCH 08/71] ncr5380: Move NCR53C400-specific code Finn Thain
2015-11-18  8:35   ` Finn Thain
2015-11-19 13:31   ` Hannes Reinecke
2015-11-19 13:31     ` Hannes Reinecke
2015-11-18  8:35 ` [PATCH 09/71] atari_NCR5380: Reset bus on driver initialization if required Finn Thain
2015-11-18  8:35   ` Finn Thain
2015-11-19 13:38   ` Hannes Reinecke
2015-11-18  8:35 ` [PATCH 10/71] atari_NCR5380: Remove RESET_BOOT, CONFIG_ATARI_SCSI_TOSHIBA_DELAY and CONFIG_ATARI_SCSI_RESET_BOOT Finn Thain
2015-11-18  8:35   ` Finn Thain
2015-11-19  3:05   ` Michael Schmitz
2015-11-19  4:05     ` Finn Thain
2015-11-19  4:43       ` Michael Schmitz
2015-11-19 13:41   ` Hannes Reinecke
2015-11-18  8:35 ` [PATCH 11/71] ncr5380: Simplify bus reset handlers Finn Thain
2015-11-18  8:35   ` Finn Thain
2015-11-19 13:56   ` Hannes Reinecke
2015-11-19 13:56     ` Hannes Reinecke
2015-11-18  8:35 ` [PATCH 12/71] ncr5380: Remove unused hostdata->aborted flag Finn Thain
2015-11-18  8:35   ` Finn Thain
2015-11-19 14:13   ` Hannes Reinecke
2015-11-18  8:35 ` [PATCH 13/71] ncr5380: Remove redundant register writes Finn Thain
2015-11-18  8:35   ` Finn Thain
2015-11-19 14:14   ` Hannes Reinecke
2015-11-19 14:14     ` Hannes Reinecke
2015-11-18  8:35 ` [PATCH 14/71] ncr5380: Use return instead of goto in NCR5380_select() Finn Thain
2015-11-18  8:35   ` Finn Thain
2015-11-19 14:14   ` Hannes Reinecke
2015-11-18  8:35 ` [PATCH 15/71] ncr5380: Always escalate bad target time-out " Finn Thain
2015-11-18  8:35   ` Finn Thain
2015-11-19 14:15   ` Hannes Reinecke
2015-11-19 14:15     ` Hannes Reinecke
2015-11-18  8:35 ` [PATCH 16/71] ncr5380: Proceed with next command after NCR5380_select() calls scsi_done Finn Thain
2015-11-18  8:35   ` Finn Thain
2015-11-19 14:16   ` Hannes Reinecke
2015-11-18  8:35 ` [PATCH 17/71] ncr5380: Keep BSY asserted when entering SELECTION phase Finn Thain
2015-11-18  8:35   ` Finn Thain
2015-11-18  8:35 ` [PATCH 18/71] ncr5380: Eliminate USLEEP_WAITLONG delay Finn Thain
2015-11-18  8:35   ` Finn Thain
2015-11-18  8:35 ` [PATCH 19/71] ncr5380: Cleanup bogus {request,release}_region() calls Finn Thain
2015-11-18  8:35   ` [PATCH 19/71] ncr5380: Cleanup bogus {request, release}_region() calls Finn Thain
2015-11-18  8:35   ` [PATCH 19/71] ncr5380: Cleanup bogus {request,release}_region() calls Finn Thain
2015-11-18  8:35 ` [PATCH 20/71] ncr5380: Introduce unbound workqueue Finn Thain
2015-11-18  8:35   ` Finn Thain
2015-11-18  8:35   ` Finn Thain
2015-11-18  8:35 ` [PATCH 21/71] ncr5380: Sleep when polling, if possible Finn Thain
2015-11-18  8:35   ` Finn Thain
2015-11-18  8:35 ` [PATCH 22/71] ncr5380: Eliminate selecting state Finn Thain
2015-11-18  8:35   ` Finn Thain
2015-11-24 19:08   ` Ondrej Zary
2015-11-25  3:17     ` Finn Thain
2015-11-25 21:59       ` Ondrej Zary
2015-11-26 10:23         ` Finn Thain
2015-11-26 19:35           ` Ondrej Zary
2015-11-26 22:32             ` Finn Thain
2015-11-28 23:13               ` Ondrej Zary
2015-11-29  0:46                 ` Finn Thain
2015-11-29  9:09                   ` Ondrej Zary
2015-11-29  9:27               ` Geert Uytterhoeven
2015-11-29 10:25                 ` Finn Thain
2015-11-29 13:50                   ` Geert Uytterhoeven
2015-11-30  2:12                     ` Finn Thain
2015-11-18  8:35 ` [PATCH 23/71] ncr5380: Always retry arbitration and selection Finn Thain
2015-11-18  8:35   ` Finn Thain
2015-11-18  8:35 ` [PATCH 24/71] ncr5380: Implement NCR5380_dma_xfer_len and remove LIMIT_TRANSFERSIZE macro Finn Thain
2015-11-18  8:35   ` Finn Thain
2015-11-18  8:35   ` Finn Thain
2015-11-18  8:35 ` [PATCH 25/71] ncr5380: Rework disconnect versus poll logic Finn Thain
2015-11-18  8:35   ` Finn Thain
2015-11-18  8:35 ` [PATCH 26/71] ncr5380: Fix NCR5380_transfer_pio() result Finn Thain
2015-11-18  8:35   ` Finn Thain
2015-11-18  8:35 ` [PATCH 27/71] ncr5380: Add missing lock in eh_abort_handler Finn Thain
2015-11-18  8:35   ` Finn Thain
2015-11-18  8:35 ` [PATCH 28/71] ncr5380: Drop DEF_SCSI_QCMD macro Finn Thain
2015-11-18  8:35   ` Finn Thain
2015-11-18  8:35 ` [PATCH 29/71] ncr5380: Remove references to linked commands Finn Thain
2015-11-18  8:35   ` Finn Thain
2015-11-18  8:35 ` [PATCH 30/71] ncr5380: Add missing break after case MESSAGE_REJECT Finn Thain
2015-11-18  8:35   ` Finn Thain
2015-11-18  8:35 ` [PATCH 31/71] ncr5380: Fix !REQ timeout in do_abort() Finn Thain
2015-11-18  8:35   ` Finn Thain
2015-11-18  8:35 ` [PATCH 32/71] ncr5380: Fix bus phase " Finn Thain
2015-11-18  8:35   ` Finn Thain
2015-11-18  8:35 ` [PATCH 33/71] atari_NCR5380: Set do_abort() timeouts Finn Thain
2015-11-18  8:35   ` Finn Thain
2015-11-18  8:35 ` [PATCH 34/71] atari_NCR5380: Use arbitration timeout Finn Thain
2015-11-18  8:35   ` Finn Thain
2015-11-18  8:35 ` [PATCH 35/71] ncr5380: Dont wait for BUS FREE after disconnect Finn Thain
2015-11-18  8:35   ` Finn Thain
2015-11-18  8:35 ` [PATCH 36/71] ncr5380: Use work_struct instead of delayed_work Finn Thain
2015-11-18  8:35   ` Finn Thain
2015-11-18  8:35 ` [PATCH 37/71] ncr5380: Standardize work queueing algorithm Finn Thain
2015-11-18  8:35   ` Finn Thain
2015-11-18  8:35 ` [PATCH 38/71] ncr5380: Remove UNSAFE macro Finn Thain
2015-11-18  8:35   ` Finn Thain
2015-11-18  8:35 ` [PATCH 39/71] ncr5380: Standardize interrupt handling Finn Thain
2015-11-18  8:35   ` Finn Thain
2015-11-18  8:35 ` [PATCH 40/71] ncr5380: Introduce NCR5380_poll_politely2 Finn Thain
2015-11-18  8:35   ` Finn Thain
2015-11-18  8:35 ` [PATCH 41/71] ncr5380: Replace redundant flags with FLAG_NO_DMA_FIXUP Finn Thain
2015-11-18  8:35   ` Finn Thain
2015-11-18  8:35 ` [PATCH 42/71] ncr5380: Replace READ_OVERRUNS macro with FLAG_NO_DMA_FIXUPS Finn Thain
2015-11-18  8:35   ` Finn Thain
2015-11-18  8:35 ` [PATCH 43/71] ncr5380: Standardize reselection handling Finn Thain
2015-11-18  8:35   ` Finn Thain
2015-11-18  8:35 ` [PATCH 44/71] ncr5380: Fix off-by-one bug in extended_msg[] bounds check Finn Thain
2015-11-18  8:35   ` Finn Thain
2015-11-18  8:35 ` [PATCH 45/71] ncr5380: Cleanup #include directives Finn Thain
2015-11-18  8:35   ` Finn Thain
2015-11-18  8:35   ` Finn Thain
2015-11-18  8:35 ` [PATCH 46/71] ncr5380: Fix NDEBUG_NO_DATAOUT flag Finn Thain
2015-11-18  8:35   ` Finn Thain
2015-11-18  8:35 ` [PATCH 47/71] ncr5380: Fix and cleanup scsi_host_template initializers Finn Thain
2015-11-18  8:35   ` Finn Thain
2015-11-18  8:35 ` [PATCH 48/71] atari_NCR5380: Fix queue_size limit Finn Thain
2015-11-18  8:35   ` Finn Thain
2015-11-18  8:35 ` [PATCH 49/71] atari_NCR5380: Introduce FLAG_DTC3181E Finn Thain
2015-11-18  8:35   ` Finn Thain
2015-11-18  8:35 ` [PATCH 50/71] ncr5380: Change instance->host_lock to hostdata->lock Finn Thain
2015-11-18  8:35   ` Finn Thain
2015-11-18  8:35 ` [PATCH 51/71] ncr5380: Remove command list debug code Finn Thain
2015-11-18  8:35   ` Finn Thain
2015-11-18  8:35   ` Finn Thain
2015-11-18  8:35 ` [PATCH 52/71] ncr5380: Remove H_NO macro and introduce dsprintk Finn Thain
2015-11-18  8:35   ` Finn Thain
2015-11-18  8:35 ` [PATCH 53/71] ncr5380: Use shost_priv helper Finn Thain
2015-11-18  8:35   ` Finn Thain
2015-11-18  8:35 ` [PATCH 54/71] ncr5380: Use dsprintk() for queue debugging Finn Thain
2015-11-18  8:35   ` Finn Thain
2015-11-18  8:35 ` [PATCH 55/71] ncr5380: Remove LIST and REMOVE macros Finn Thain
2015-11-18  8:35   ` Finn Thain
2015-11-18  8:35 ` [PATCH 56/71] ncr5380: Remove redundant volatile qualifiers Finn Thain
2015-11-18  8:35   ` Finn Thain
2015-11-18  8:35 ` [PATCH 57/71] ncr5380: Use standard list data structure Finn Thain
2015-11-18  8:35   ` Finn Thain
2015-11-18  8:35   ` Finn Thain
2015-11-18  8:35 ` [PATCH 58/71] ncr5380: Refactor command completion Finn Thain
2015-11-18  8:35   ` Finn Thain
2015-11-18  8:35 ` [PATCH 59/71] ncr5380: Fix autosense bugs Finn Thain
2015-11-18  8:35   ` Finn Thain
2015-11-18  8:35 ` [PATCH 60/71] ncr5380: Implement new eh_abort_handler Finn Thain
2015-11-18  8:35   ` Finn Thain
2015-11-18  8:35 ` [PATCH 61/71] ncr5380: Fix EH during arbitration and selection Finn Thain
2015-11-18  8:35   ` Finn Thain
2015-11-18  8:35 ` [PATCH 62/71] ncr5380: Implement new eh_bus_reset_handler Finn Thain
2015-11-18  8:35   ` Finn Thain
2015-11-18  8:35 ` [PATCH 63/71] atari_NCR5380: Remove HOSTNO macro from printk() and seq_printf() calls Finn Thain
2015-11-18  8:35   ` Finn Thain
2015-11-18  8:35 ` [PATCH 64/71] atari_NCR5380: Eliminate HOSTNO macro Finn Thain
2015-11-18  8:35   ` Finn Thain
2015-11-18  8:36 ` [PATCH 65/71] atari_scsi, sun3_scsi: Remove global Scsi_Host pointer Finn Thain
2015-11-18  8:36   ` Finn Thain
2015-11-18  8:36 ` [PATCH 66/71] ncr5380: Fix soft lockups Finn Thain
2015-11-18  8:36   ` Finn Thain
2015-11-18  8:36 ` [PATCH 67/71] ncr5380: Cleanup comments Finn Thain
2015-11-18  8:36   ` Finn Thain
2015-11-18  8:36 ` [PATCH 68/71] ncr5380: Fix whitespace issues using regexp Finn Thain
2015-11-18  8:36   ` Finn Thain
2015-11-18  8:36 ` [PATCH 69/71] ncr5380: Merge changes from atari_NCR5380.c Finn Thain
2015-11-18  8:36   ` Finn Thain
2015-11-18  8:36 ` [PATCH 70/71] atari_NCR5380: Merge changes from NCR5380.c Finn Thain
2015-11-18  8:36   ` Finn Thain
2015-11-18  8:36 ` [PATCH 71/71] ncr5380: Cleanup whitespace and parentheses Finn Thain
2015-11-18  8:36   ` Finn Thain
2015-11-18 11:35 ` [PATCH 00/71] More fixes, cleanup and modernization for NCR5380 drivers Ondrej Zary
2015-11-19  2:24   ` Finn Thain
2015-11-19  2:52     ` Michael Schmitz
2015-11-19  7:48     ` Ondrej Zary
2015-11-19 22:50     ` Ondrej Zary
2015-11-20  1:41       ` Finn Thain
2015-11-20  7:21         ` Finn Thain
2015-11-20  7:33           ` Christoph Hellwig
2015-11-20  8:19             ` Finn Thain
2015-11-20  9:16               ` Ondrej Zary
2015-11-20 10:00               ` Christoph Hellwig
2015-11-20 10:53                 ` Finn Thain
2015-11-20 11:40                   ` Ondrej Zary
2015-11-20 11:45                     ` Christoph Hellwig
2015-11-20 12:23                     ` Geert Uytterhoeven
2015-11-20 12:46                       ` Ondrej Zary
2015-11-20  7:35         ` Ondrej Zary
2015-11-20 18:29         ` Ondrej Zary
2015-11-21  1:58           ` Finn Thain
2015-11-21 13:01             ` Ondrej Zary
2015-11-21 23:07               ` Ondrej Zary
2015-11-21 23:32               ` Finn Thain
2015-11-23 22:55                 ` Ondrej Zary
2015-11-24  1:21                   ` Finn Thain
2015-11-24  8:04                     ` Ondrej Zary
2015-11-24  9:13                       ` Finn Thain
2015-11-24 12:03                         ` Ondrej Zary
2015-11-24 18:04                           ` Ondrej Zary
2015-11-24 21:40                         ` Ondrej Zary
2015-11-25  2:10                           ` Finn Thain
2015-11-25  9:04                             ` Ondrej Zary
2015-11-25 11:50                               ` Finn Thain
2015-11-25 23:01                               ` Ondrej Zary
2015-11-25 21:34 ` [PATCH 72/71] ncr5380: Fix pseudo-DMA Ondrej Zary
2015-11-29  9:39 ` [RFC PATCH 73/71] ncr5380: Use runtime register mapping Ondrej Zary
2015-11-30 11:50   ` Finn Thain
2015-11-29  9:39 ` [RFC PATCH 74/71] ncr5380: Enable PDMA for NCR53C400A Ondrej Zary
2015-11-30 11:52   ` Finn Thain
2015-11-30 12:04   ` Finn Thain
2015-11-30 13:40     ` Ondrej Zary
2015-12-06  3:20       ` Finn Thain
2015-11-29 10:01 ` [RFC PATCH 75/71] ncr5380: Remove FLAG_DTC3181E Ondrej Zary
2015-11-30  4:56   ` Finn Thain
2015-12-03 23:03 ` [RFC PATCH 76/71] ncr5380: Enable PDMA for DTC chips Ondrej Zary
2015-12-04  0:12   ` Julian Calaby
2015-12-04  8:38     ` Finn Thain
2015-12-05  1:32       ` Julian Calaby
2015-12-05  2:12         ` Finn Thain
2015-12-05  2:38           ` Julian Calaby
2015-12-04  9:08   ` Finn Thain
2015-12-04  9:32     ` Ondrej Zary
2015-12-04  9:20   ` Finn Thain
2015-12-03 23:03 ` [RFC PATCH 77/71] ncr5380: Fix wait for 53C80 registers registers after PDMA Ondrej Zary
2015-12-04 21:00 ` [PATCH 73/71] ncr5380: Use runtime register mapping Ondrej Zary
2015-12-06  3:39   ` Finn Thain
2015-12-06  8:42     ` Geert Uytterhoeven
2015-12-04 21:02 ` [PATCH 74/71] ncr5380: Enable PDMA for NCR53C400A Ondrej Zary
2015-12-06  3:41   ` Finn Thain
2015-12-04 21:17 ` [PATCH 76/71] ncr5380: Enable PDMA for DTC chips Ondrej Zary
2015-12-06  3:40   ` Finn Thain
2015-12-06 22:47     ` Ondrej Zary
2015-12-05 21:18 ` [RFC PATCH 78/71] ncr5380: Add support for HP 53C400A-based cards (C2502) Ondrej Zary
2015-12-06  3:39   ` Finn Thain
2015-12-06 22:20 ` [PATCH v2 73/71] ncr5380: Use runtime register mapping Ondrej Zary
2015-12-06 22:21 ` [PATCH v2 74/71] ncr5380: Enable PDMA for NCR53C400A Ondrej Zary
2015-12-08  2:05   ` Finn Thain
2015-12-09 13:39     ` Ondrej Zary
2015-12-10 23:39       ` Finn Thain
2015-12-06 22:55 ` [PATCH v2 76/71] ncr5380: Enable PDMA for DTC chips Ondrej Zary
2015-12-06 23:17 ` [PATCH v2 77/71] ncr5380: Fix wait for 53C80 registers registers after PDMA Ondrej Zary
2015-12-07  3:16   ` Finn Thain
2015-12-07  8:08     ` Ondrej Zary
2015-12-06 23:20 ` [PATCH v3 76/71] ncr5380: Enable PDMA for DTC chips Ondrej Zary
2015-12-08  7:51 ` [PATCH v2 78/71] ncr5380: Add support for HP 53C400A-based cards (C2502) Ondrej Zary
2015-12-08 11:40   ` Finn Thain
2015-12-09 11:33     ` Ondrej Zary
2015-12-10 23:38       ` Finn Thain
2015-12-09 12:11 ` [PATCH v3 " Ondrej Zary

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.