Re: [Patch v2] wd719x: pass GFP_ATOMIC instead of GFP_KERNEL linux-ker...@vger.kernel.org

2019-05-30 Thread Ondrej Zary
On Thursday 30 May 2019 20:10:44 Hariprasad Kelam wrote:
> On Wed, May 29, 2019 at 02:13:18PM -0700, David Rientjes wrote:
> > On Wed, 29 May 2019, Hariprasad Kelam wrote:
> > 
> > > dont acquire lock before calling wd719x_chip_init.
> > > 
> > > Issue identified by coccicheck
> > > 
> > > Signed-off-by: Hariprasad Kelam 
> > > -
> > > changes in v1: Replace GFP_KERNEL with GFP_ATOMIC.
> > > changes in v2: Call wd719x_chip_init  without lock as suggested
> > >   in review
> > 
> > Why was host_lock taken here initially?  I assume it's to protect some 
> > race in init that leads to an undefined state.
> 
> wd719x_chip_init is getting called from wd719x_host_reset
> and wd719x_board_found.
> 
> In wd719x_board_found case its not acquiring any lock.
> In wd719x_host_reset it is called under spin_lock.
> 
> Acquiring spin_lock in wd719x_host_reset is there from initial commit
> so its better we wont remove this lock.

Looks like I haven't tested it properly before. Host reset is broken - sg_reset 
-N -H /dev/sdX will oops:

wd719x :02:01.0: host reset requested
[ cut here ]
kernel BUG at fs/buffer.c:1218!
invalid opcode:  [#1] SMP
CPU: 0 PID: 1913 Comm: sg_reset Not tainted 5.1.0+ #323
Hardware name:  /848P-ICH5, BIOS 6.00 PG 02/03/2005
EIP: check_irqs_on+0xb/0xf
...

That's because of request_firmware called under the spin lock, as Christoph 
pointed out.
Patch v2 is also wrong - wd719x_finish_cmd must be called under lock.

I'm currently testing a proper fix (disable chip and flush SCBs under lock, 
then initialize chip without lock). It works mostly but I can crash it easily 
by doing a device reset under load (e.g. dd from a SCSI drive) and then doing a 
host reset - NULL pointer dereference in list_del.

> I think we Patch v1 is  correct fix(pass GFP_ATOMIC instead of GPF_KERNEL )
> 
> 


-- 
Ondrej Zary


[PATCH 1/4 v2] fdomain: Resurrect driver (core)

2019-04-29 Thread Ondrej Zary
Future Domain TMC-16xx/TMC-3260 SCSI driver.

This is the core driver, common for PCI, ISA and PCMCIA cards.

Signed-off-by: Ondrej Zary 
---
Changes in v2:
 - fdomain_reset marked static
---
 drivers/scsi/Kconfig   |   4 +
 drivers/scsi/Makefile  |   1 +
 drivers/scsi/fdomain.c | 600 +
 drivers/scsi/fdomain.h |  63 ++
 4 files changed, 668 insertions(+)
 create mode 100644 drivers/scsi/fdomain.c
 create mode 100644 drivers/scsi/fdomain.h

diff --git a/drivers/scsi/Kconfig b/drivers/scsi/Kconfig
index d528018e6fa8..3d6b1f47cbb5 100644
--- a/drivers/scsi/Kconfig
+++ b/drivers/scsi/Kconfig
@@ -663,6 +663,10 @@ config SCSI_DMX3191D
  To compile this driver as a module, choose M here: the
  module will be called dmx3191d.
 
+config SCSI_FDOMAIN
+   tristate
+   depends on SCSI
+
 config SCSI_GDTH
tristate "Intel/ICP (former GDT SCSI Disk Array) RAID Controller 
support"
depends on PCI && SCSI
diff --git a/drivers/scsi/Makefile b/drivers/scsi/Makefile
index 8826111fdf4a..b8fbc6d2de54 100644
--- a/drivers/scsi/Makefile
+++ b/drivers/scsi/Makefile
@@ -76,6 +76,7 @@ obj-$(CONFIG_SCSI_AIC94XX)+= aic94xx/
 obj-$(CONFIG_SCSI_PM8001)  += pm8001/
 obj-$(CONFIG_SCSI_ISCI)+= isci/
 obj-$(CONFIG_SCSI_IPS) += ips.o
+obj-$(CONFIG_SCSI_FDOMAIN) += fdomain.o
 obj-$(CONFIG_SCSI_GENERIC_NCR5380) += g_NCR5380.o
 obj-$(CONFIG_SCSI_QLOGIC_FAS)  += qlogicfas408.o   qlogicfas.o
 obj-$(CONFIG_PCMCIA_QLOGIC)+= qlogicfas408.o
diff --git a/drivers/scsi/fdomain.c b/drivers/scsi/fdomain.c
new file mode 100644
index ..e43fdd1ab3a8
--- /dev/null
+++ b/drivers/scsi/fdomain.c
@@ -0,0 +1,600 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Driver for Future Domain TMC-16x0 and TMC-3260 SCSI host adapters
+ * Copyright 2019 Ondrej Zary
+ *
+ * Original driver by
+ * Rickard E. Faith, fa...@cs.unc.edu
+ *
+ * Future Domain BIOS versions supported for autodetect:
+ *2.0, 3.0, 3.2, 3.4 (1.0), 3.5 (2.0), 3.6, 3.61
+ * Chips supported:
+ *TMC-1800, TMC-18C50, TMC-18C30, TMC-36C70
+ * Boards supported:
+ *Future Domain TMC-1650, TMC-1660, TMC-1670, TMC-1680, TMC-1610M/MER/MEX
+ *Future Domain TMC-3260 (PCI)
+ *Quantum ISA-200S, ISA-250MG
+ *Adaptec AHA-2920A (PCI) [BUT *NOT* AHA-2920C -- use aic7xxx instead]
+ *IBM ?
+ *
+ * NOTE:
+ *
+ * The Adaptec AHA-2920C has an Adaptec AIC-7850 chip on it.
+ * Use the aic7xxx driver for this board.
+ *
+ * The Adaptec AHA-2920A has a Future Domain chip on it, so this is the right
+ * driver for that card.  Unfortunately, the boxes will probably just say
+ * "2920", so you'll have to look on the card for a Future Domain logo, or a
+ * letter after the 2920.
+ *
+ * If you have a TMC-8xx or TMC-9xx board, then this is not the driver for
+ * your board.
+ *
+ * DESCRIPTION:
+ *
+ * This is the Linux low-level SCSI driver for Future Domain TMC-1660/1680
+ * TMC-1650/1670, and TMC-3260 SCSI host adapters.  The 1650 and 1670 have a
+ * 25-pin external connector, whereas the 1660 and 1680 have a SCSI-2 50-pin
+ * high-density external connector.  The 1670 and 1680 have floppy disk
+ * controllers built in.  The TMC-3260 is a PCI bus card.
+ *
+ * Future Domain's older boards are based on the TMC-1800 chip, and this
+ * driver was originally written for a TMC-1680 board with the TMC-1800 chip.
+ * More recently, boards are being produced with the TMC-18C50 and TMC-18C30
+ * chips.
+ *
+ * Please note that the drive ordering that Future Domain implemented in BIOS
+ * versions 3.4 and 3.5 is the opposite of the order (currently) used by the
+ * rest of the SCSI industry.
+ *
+ *
+ * REFERENCES USED:
+ *
+ * "TMC-1800 SCSI Chip Specification (FDC-1800T)", Future Domain Corporation,
+ * 1990.
+ *
+ * "Technical Reference Manual: 18C50 SCSI Host Adapter Chip", Future Domain
+ * Corporation, January 1992.
+ *
+ * "LXT SCSI Products: Specifications and OEM Technical Manual (Revision
+ * B/September 1991)", Maxtor Corporation, 1991.
+ *
+ * "7213S product Manual (Revision P3)", Maxtor Corporation, 1992.
+ *
+ * "Draft Proposed American National Standard: Small Computer System
+ * Interface - 2 (SCSI-2)", Global Engineering Documents. (X3T9.2/86-109,
+ * revision 10h, October 17, 1991)
+ *
+ * Private communications, Drew Eckhardt (d...@cs.colorado.edu) and Eric
+ * Youngdale (er...@cais.com), 1992.
+ *
+ * Private communication, Tuong Le (Future Domain Engineering department),
+ * 1994. (Disk geometry computations for Future Domain BIOS version 3.4, and
+ * TMC-18C30 detection.)
+ *
+ * Hogan, Thom. The Programmer's PC Sourcebook. Microsoft Press, 1988. Page
+ * 60 (2.39: Disk Partition Table Layout).
+ *
+ * "18C30 Technical Reference Manual", Future Domain Corporation, 1993, page
+ * 6-1.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+

[PATCH 1/4] fdomain: Resurrect driver (core)

2019-04-28 Thread Ondrej Zary
Future Domain TMC-16xx/TMC-3260 SCSI driver.

This is the core driver, common for PCI, ISA and PCMCIA cards.

Signed-off-by: Ondrej Zary 
---
 drivers/scsi/Kconfig   |   4 +
 drivers/scsi/Makefile  |   1 +
 drivers/scsi/fdomain.c | 600 +
 drivers/scsi/fdomain.h |  63 ++
 4 files changed, 668 insertions(+)
 create mode 100644 drivers/scsi/fdomain.c
 create mode 100644 drivers/scsi/fdomain.h

diff --git a/drivers/scsi/Kconfig b/drivers/scsi/Kconfig
index d528018e6fa8..3d6b1f47cbb5 100644
--- a/drivers/scsi/Kconfig
+++ b/drivers/scsi/Kconfig
@@ -663,6 +663,10 @@ config SCSI_DMX3191D
  To compile this driver as a module, choose M here: the
  module will be called dmx3191d.
 
+config SCSI_FDOMAIN
+   tristate
+   depends on SCSI
+
 config SCSI_GDTH
tristate "Intel/ICP (former GDT SCSI Disk Array) RAID Controller 
support"
depends on PCI && SCSI
diff --git a/drivers/scsi/Makefile b/drivers/scsi/Makefile
index 8826111fdf4a..b8fbc6d2de54 100644
--- a/drivers/scsi/Makefile
+++ b/drivers/scsi/Makefile
@@ -76,6 +76,7 @@ obj-$(CONFIG_SCSI_AIC94XX)+= aic94xx/
 obj-$(CONFIG_SCSI_PM8001)  += pm8001/
 obj-$(CONFIG_SCSI_ISCI)+= isci/
 obj-$(CONFIG_SCSI_IPS) += ips.o
+obj-$(CONFIG_SCSI_FDOMAIN) += fdomain.o
 obj-$(CONFIG_SCSI_GENERIC_NCR5380) += g_NCR5380.o
 obj-$(CONFIG_SCSI_QLOGIC_FAS)  += qlogicfas408.o   qlogicfas.o
 obj-$(CONFIG_PCMCIA_QLOGIC)+= qlogicfas408.o
diff --git a/drivers/scsi/fdomain.c b/drivers/scsi/fdomain.c
new file mode 100644
index ..edf75c7f8e3f
--- /dev/null
+++ b/drivers/scsi/fdomain.c
@@ -0,0 +1,600 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Driver for Future Domain TMC-16x0 and TMC-3260 SCSI host adapters
+ * Copyright 2019 Ondrej Zary
+ *
+ * Original driver by
+ * Rickard E. Faith, fa...@cs.unc.edu
+ *
+ * Future Domain BIOS versions supported for autodetect:
+ *2.0, 3.0, 3.2, 3.4 (1.0), 3.5 (2.0), 3.6, 3.61
+ * Chips supported:
+ *TMC-1800, TMC-18C50, TMC-18C30, TMC-36C70
+ * Boards supported:
+ *Future Domain TMC-1650, TMC-1660, TMC-1670, TMC-1680, TMC-1610M/MER/MEX
+ *Future Domain TMC-3260 (PCI)
+ *Quantum ISA-200S, ISA-250MG
+ *Adaptec AHA-2920A (PCI) [BUT *NOT* AHA-2920C -- use aic7xxx instead]
+ *IBM ?
+ *
+ * NOTE:
+ *
+ * The Adaptec AHA-2920C has an Adaptec AIC-7850 chip on it.
+ * Use the aic7xxx driver for this board.
+ *
+ * The Adaptec AHA-2920A has a Future Domain chip on it, so this is the right
+ * driver for that card.  Unfortunately, the boxes will probably just say
+ * "2920", so you'll have to look on the card for a Future Domain logo, or a
+ * letter after the 2920.
+ *
+ * If you have a TMC-8xx or TMC-9xx board, then this is not the driver for
+ * your board.
+ *
+ * DESCRIPTION:
+ *
+ * This is the Linux low-level SCSI driver for Future Domain TMC-1660/1680
+ * TMC-1650/1670, and TMC-3260 SCSI host adapters.  The 1650 and 1670 have a
+ * 25-pin external connector, whereas the 1660 and 1680 have a SCSI-2 50-pin
+ * high-density external connector.  The 1670 and 1680 have floppy disk
+ * controllers built in.  The TMC-3260 is a PCI bus card.
+ *
+ * Future Domain's older boards are based on the TMC-1800 chip, and this
+ * driver was originally written for a TMC-1680 board with the TMC-1800 chip.
+ * More recently, boards are being produced with the TMC-18C50 and TMC-18C30
+ * chips.
+ *
+ * Please note that the drive ordering that Future Domain implemented in BIOS
+ * versions 3.4 and 3.5 is the opposite of the order (currently) used by the
+ * rest of the SCSI industry.
+ *
+ *
+ * REFERENCES USED:
+ *
+ * "TMC-1800 SCSI Chip Specification (FDC-1800T)", Future Domain Corporation,
+ * 1990.
+ *
+ * "Technical Reference Manual: 18C50 SCSI Host Adapter Chip", Future Domain
+ * Corporation, January 1992.
+ *
+ * "LXT SCSI Products: Specifications and OEM Technical Manual (Revision
+ * B/September 1991)", Maxtor Corporation, 1991.
+ *
+ * "7213S product Manual (Revision P3)", Maxtor Corporation, 1992.
+ *
+ * "Draft Proposed American National Standard: Small Computer System
+ * Interface - 2 (SCSI-2)", Global Engineering Documents. (X3T9.2/86-109,
+ * revision 10h, October 17, 1991)
+ *
+ * Private communications, Drew Eckhardt (d...@cs.colorado.edu) and Eric
+ * Youngdale (er...@cais.com), 1992.
+ *
+ * Private communication, Tuong Le (Future Domain Engineering department),
+ * 1994. (Disk geometry computations for Future Domain BIOS version 3.4, and
+ * TMC-18C30 detection.)
+ *
+ * Hogan, Thom. The Programmer's PC Sourcebook. Microsoft Press, 1988. Page
+ * 60 (2.39: Disk Partition Table Layout).
+ *
+ * "18C30 Technical Reference Manual", Future Domain Corporation, 1993, page
+ * 6-1.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+

[PATCH 4/4] fdomain: Resurrect driver (PCMCIA support)

2019-04-28 Thread Ondrej Zary
Future Domain PCMCIA SCSI support card support.

Currently untested.

Signed-off-by: Ondrej Zary 
---
 drivers/scsi/pcmcia/Kconfig  | 10 +
 drivers/scsi/pcmcia/Makefile |  1 +
 drivers/scsi/pcmcia/fdomain_cs.c | 89 
 3 files changed, 100 insertions(+)
 create mode 100644 drivers/scsi/pcmcia/fdomain_cs.c

diff --git a/drivers/scsi/pcmcia/Kconfig b/drivers/scsi/pcmcia/Kconfig
index 2d435f105b16..169d93f90a30 100644
--- a/drivers/scsi/pcmcia/Kconfig
+++ b/drivers/scsi/pcmcia/Kconfig
@@ -19,6 +19,16 @@ config PCMCIA_AHA152X
  To compile this driver as a module, choose M here: the
  module will be called aha152x_cs.
 
+config PCMCIA_FDOMAIN
+   tristate "Future Domain PCMCIA support"
+   select SCSI_FDOMAIN
+   help
+ Say Y here if you intend to attach this type of PCMCIA SCSI host
+ adapter to your computer.
+
+ To compile this driver as a module, choose M here: the
+ module will be called fdomain_cs.
+
 config PCMCIA_NINJA_SCSI
tristate "NinjaSCSI-3 / NinjaSCSI-32Bi (16bit) PCMCIA support"
depends on !64BIT
diff --git a/drivers/scsi/pcmcia/Makefile b/drivers/scsi/pcmcia/Makefile
index a5a24dd44e7e..02f5b44a2685 100644
--- a/drivers/scsi/pcmcia/Makefile
+++ b/drivers/scsi/pcmcia/Makefile
@@ -4,6 +4,7 @@ ccflags-y   := -I $(srctree)/drivers/scsi
 
 # 16-bit client drivers
 obj-$(CONFIG_PCMCIA_QLOGIC)+= qlogic_cs.o
+obj-$(CONFIG_PCMCIA_FDOMAIN)   += fdomain_cs.o
 obj-$(CONFIG_PCMCIA_AHA152X)   += aha152x_cs.o
 obj-$(CONFIG_PCMCIA_NINJA_SCSI)+= nsp_cs.o
 obj-$(CONFIG_PCMCIA_SYM53C500) += sym53c500_cs.o
diff --git a/drivers/scsi/pcmcia/fdomain_cs.c b/drivers/scsi/pcmcia/fdomain_cs.c
new file mode 100644
index ..eee1379ad67b
--- /dev/null
+++ b/drivers/scsi/pcmcia/fdomain_cs.c
@@ -0,0 +1,89 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MPL-1.1)
+/*
+ * Driver for Future Domain-compatible PCMCIA SCSI cards
+ * Copyright 2019 Ondrej Zary
+ *
+ * The initial developer of the original code is David A. Hinds
+ * .  Portions created by David A. Hinds
+ * are Copyright (C) 1999 David A. Hinds.  All Rights Reserved.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include "fdomain.h"
+
+MODULE_AUTHOR("Ondrej Zary, David Hinds");
+MODULE_DESCRIPTION("Future Domain PCMCIA SCSI driver");
+MODULE_LICENSE("Dual MPL/GPL");
+
+static int fdomain_config_check(struct pcmcia_device *p_dev, void *priv_data)
+{
+   p_dev->io_lines = 10;
+   p_dev->resource[0]->end = 0x10;
+   p_dev->resource[0]->flags &= ~IO_DATA_PATH_WIDTH;
+   p_dev->resource[0]->flags |= IO_DATA_PATH_WIDTH_AUTO;
+   return pcmcia_request_io(p_dev);
+}
+
+static int fdomain_probe(struct pcmcia_device *link)
+{
+   int ret;
+   struct Scsi_Host *sh;
+
+   link->config_flags |= CONF_ENABLE_IRQ | CONF_AUTO_SET_IO;
+   link->config_regs = PRESENT_OPTION;
+
+   ret = pcmcia_loop_config(link, fdomain_config_check, NULL);
+   if (ret)
+   return ret;
+
+   ret = pcmcia_enable_device(link);
+   if (ret)
+   goto fail;
+
+   sh = fdomain_create(link->resource[0]->start, link->irq, 7, 0, NULL,
+   &link->dev);
+   if (!sh) {
+   dev_err(&link->dev, "Controller initialization failed");
+   ret = -ENODEV;
+   goto fail;
+   }
+
+   link->priv = sh;
+
+   return 0;
+
+fail:
+   pcmcia_disable_device(link);
+   return ret;
+}
+
+static void fdomain_remove(struct pcmcia_device *link)
+{
+   fdomain_destroy(link->priv);
+   pcmcia_disable_device(link);
+}
+
+static const struct pcmcia_device_id fdomain_ids[] = {
+   PCMCIA_DEVICE_PROD_ID12("IBM Corp.", "SCSI PCMCIA Card", 0xe3736c88,
+   0x859cad20),
+   PCMCIA_DEVICE_PROD_ID1("SCSI PCMCIA Adapter Card", 0x8dacb57e),
+   PCMCIA_DEVICE_PROD_ID12(" SIMPLE TECHNOLOGY Corporation",
+   "SCSI PCMCIA Credit Card Controller",
+   0x182bdafe, 0xc80d106f),
+   PCMCIA_DEVICE_NULL,
+};
+MODULE_DEVICE_TABLE(pcmcia, fdomain_ids);
+
+static struct pcmcia_driver fdomain_cs_driver = {
+   .owner  = THIS_MODULE,
+   .name   = "fdomain_cs",
+   .probe  = fdomain_probe,
+   .remove = fdomain_remove,
+   .id_table   = fdomain_ids,
+};
+
+module_pcmcia_driver(fdomain_cs_driver);
-- 
Ondrej Zary



[PATCH 2/4] fdomain: Resurrect driver (PCI support)

2019-04-28 Thread Ondrej Zary
Future Domain TMC-3260/AHA-2920A PCI card support.

Tested on Adaptec AHA-2920A PCI card.

Signed-off-by: Ondrej Zary 
---
 drivers/scsi/Kconfig   | 17 
 drivers/scsi/Makefile  |  1 +
 drivers/scsi/fdomain_pci.c | 68 ++
 3 files changed, 86 insertions(+)
 create mode 100644 drivers/scsi/fdomain_pci.c

diff --git a/drivers/scsi/Kconfig b/drivers/scsi/Kconfig
index 3d6b1f47cbb5..f9d058a07e2a 100644
--- a/drivers/scsi/Kconfig
+++ b/drivers/scsi/Kconfig
@@ -667,6 +667,23 @@ config SCSI_FDOMAIN
tristate
depends on SCSI
 
+config SCSI_FDOMAIN_PCI
+   tristate "Future Domain TMC-3260/AHA-2920A PCI SCSI support"
+   depends on PCI && SCSI
+   select SCSI_FDOMAIN
+   help
+ This is support for Future Domain's PCI SCSI host adapters (TMC-3260)
+ and other adapters with PCI bus based on the Future Domain chipsets
+ (Adaptec AHA-2920A).
+
+ NOTE: Newer Adaptec AHA-2920C boards use the Adaptec AIC-7850 chip
+ and should use the aic7xxx driver ("Adaptec AIC7xxx chipset SCSI
+ controller support"). This Future Domain driver works with the older
+ Adaptec AHA-2920A boards with a Future Domain chip on them.
+
+ To compile this driver as a module, choose M here: the
+ module will be called fdomain_pci.
+
 config SCSI_GDTH
tristate "Intel/ICP (former GDT SCSI Disk Array) RAID Controller 
support"
depends on PCI && SCSI
diff --git a/drivers/scsi/Makefile b/drivers/scsi/Makefile
index b8fbc6d2de54..f6cc4fbe6957 100644
--- a/drivers/scsi/Makefile
+++ b/drivers/scsi/Makefile
@@ -77,6 +77,7 @@ obj-$(CONFIG_SCSI_PM8001) += pm8001/
 obj-$(CONFIG_SCSI_ISCI)+= isci/
 obj-$(CONFIG_SCSI_IPS) += ips.o
 obj-$(CONFIG_SCSI_FDOMAIN) += fdomain.o
+obj-$(CONFIG_SCSI_FDOMAIN_PCI) += fdomain_pci.o
 obj-$(CONFIG_SCSI_GENERIC_NCR5380) += g_NCR5380.o
 obj-$(CONFIG_SCSI_QLOGIC_FAS)  += qlogicfas408.o   qlogicfas.o
 obj-$(CONFIG_PCMCIA_QLOGIC)+= qlogicfas408.o
diff --git a/drivers/scsi/fdomain_pci.c b/drivers/scsi/fdomain_pci.c
new file mode 100644
index ..381a7157c078
--- /dev/null
+++ b/drivers/scsi/fdomain_pci.c
@@ -0,0 +1,68 @@
+// SPDX-License-Identifier: GPL-2.0
+
+#include 
+#include 
+#include "fdomain.h"
+
+static int fdomain_pci_probe(struct pci_dev *pdev,
+const struct pci_device_id *d)
+{
+   int err;
+   struct Scsi_Host *sh;
+
+   err = pci_enable_device(pdev);
+   if (err)
+   goto fail;
+
+   err = pci_request_regions(pdev, "fdomain_pci");
+   if (err)
+   goto disable_device;
+
+   err = -ENODEV;
+   if (pci_resource_len(pdev, 0) == 0)
+   goto release_region;
+
+   sh = fdomain_create(pci_resource_start(pdev, 0), pdev->irq, 7, 0, NULL,
+   &pdev->dev);
+   if (!sh)
+   goto release_region;
+
+   pci_set_drvdata(pdev, sh);
+   return 0;
+
+release_region:
+   pci_release_regions(pdev);
+disable_device:
+   pci_disable_device(pdev);
+fail:
+   return err;
+}
+
+static void fdomain_pci_remove(struct pci_dev *pdev)
+{
+   struct Scsi_Host *sh = pci_get_drvdata(pdev);
+
+   fdomain_destroy(sh);
+   pci_release_regions(pdev);
+   pci_disable_device(pdev);
+}
+
+static struct pci_device_id fdomain_pci_table[] = {
+   { PCI_DEVICE(PCI_VENDOR_ID_FD, PCI_DEVICE_ID_FD_36C70) },
+   {}
+};
+MODULE_DEVICE_TABLE(pci, fdomain_pci_table);
+
+static struct pci_driver fdomain_pci_driver = {
+   .name   = "fdomain_pci",
+   .id_table   = fdomain_pci_table,
+   .probe  = fdomain_pci_probe,
+   .remove = fdomain_pci_remove,
+   .driver.pm      = FDOMAIN_PM_OPS,
+};
+
+module_pci_driver(fdomain_pci_driver);
+
+MODULE_AUTHOR("Ondrej Zary, Rickard E. Faith");
+MODULE_DESCRIPTION("Future Domain TMC-3260 PCI SCSI driver");
+MODULE_LICENSE("GPL");
-- 
Ondrej Zary



[PATCH 0/4] fdomain: Resurrect driver (modular version)

2019-04-28 Thread Ondrej Zary


Resurrect previously removed fdomain driver, in modern style.
Initialization is rewritten completely, with support for multiple cards,
no more global state variables.
Most of the code from interrupt handler is moved to a workqueue.

This is a modularized version with core separated from bus-specific drivers
(PCI, ISA and PCMCIA). Only PCI driver is tested for now. The other two could
be dropped until they get tested.

Changes since RFC:
 - multi-line comment style, some coding style
 - usage of scsi_k(un)map_atomic_sg for buffer access
 - static marking of fdomain_host_reset and fdomain_template
 - IRQ lookup moved to ISA bus driver
 - EXPORT_SYMBOL_GPL

-- 
Ondrej Zary


[PATCH 3/4] fdomain: Resurrect driver (ISA support)

2019-04-28 Thread Ondrej Zary
Future Domain 16xx ISA SCSI support card support.

Currently untested.

Signed-off-by: Ondrej Zary 
---
 drivers/scsi/Kconfig   |  14 +++
 drivers/scsi/Makefile  |   1 +
 drivers/scsi/fdomain_isa.c | 231 +
 3 files changed, 246 insertions(+)
 create mode 100644 drivers/scsi/fdomain_isa.c

diff --git a/drivers/scsi/Kconfig b/drivers/scsi/Kconfig
index f9d058a07e2a..2ea77dafbc00 100644
--- a/drivers/scsi/Kconfig
+++ b/drivers/scsi/Kconfig
@@ -684,6 +684,20 @@ config SCSI_FDOMAIN_PCI
  To compile this driver as a module, choose M here: the
  module will be called fdomain_pci.
 
+config SCSI_FDOMAIN_ISA
+   tristate "Future Domain 16xx ISA SCSI support"
+   depends on ISA && SCSI
+   select CHECK_SIGNATURE
+   select SCSI_FDOMAIN
+   help
+ This is support for Future Domain's 16-bit SCSI host adapters
+ (TMC-1660/1680, TMC-1650/1670, TMC-1610M/MER/MEX) and other adapters
+ with ISA bus based on the Future Domain chipsets (Quantum ISA-200S,
+ ISA-250MG; and at least one IBM board).
+
+ To compile this driver as a module, choose M here: the
+ module will be called fdomain_isa.
+
 config SCSI_GDTH
tristate "Intel/ICP (former GDT SCSI Disk Array) RAID Controller 
support"
depends on PCI && SCSI
diff --git a/drivers/scsi/Makefile b/drivers/scsi/Makefile
index f6cc4fbe6957..2e2c777d 100644
--- a/drivers/scsi/Makefile
+++ b/drivers/scsi/Makefile
@@ -78,6 +78,7 @@ obj-$(CONFIG_SCSI_ISCI)   += isci/
 obj-$(CONFIG_SCSI_IPS) += ips.o
 obj-$(CONFIG_SCSI_FDOMAIN) += fdomain.o
 obj-$(CONFIG_SCSI_FDOMAIN_PCI) += fdomain_pci.o
+obj-$(CONFIG_SCSI_FDOMAIN_ISA) += fdomain_isa.o
 obj-$(CONFIG_SCSI_GENERIC_NCR5380) += g_NCR5380.o
 obj-$(CONFIG_SCSI_QLOGIC_FAS)  += qlogicfas408.o   qlogicfas.o
 obj-$(CONFIG_PCMCIA_QLOGIC)+= qlogicfas408.o
diff --git a/drivers/scsi/fdomain_isa.c b/drivers/scsi/fdomain_isa.c
new file mode 100644
index ..3008d5118d7a
--- /dev/null
+++ b/drivers/scsi/fdomain_isa.c
@@ -0,0 +1,231 @@
+// SPDX-License-Identifier: GPL-2.0
+
+#include 
+#include 
+#include 
+#include 
+#include "fdomain.h"
+
+#define MAXBOARDS_PARAM 4
+static int io[MAXBOARDS_PARAM] = { 0, 0, 0, 0 };
+module_param_hw_array(io, int, ioport, NULL, 0);
+MODULE_PARM_DESC(io, "base I/O address of controller (0x140, 0x150, 0x160, 
0x170)");
+
+static int irq[MAXBOARDS_PARAM] = { 0, 0, 0, 0 };
+module_param_hw_array(irq, int, irq, NULL, 0);
+MODULE_PARM_DESC(irq, "IRQ of controller (0=auto [default])");
+
+static int scsi_id[MAXBOARDS_PARAM] = { 0, 0, 0, 0 };
+module_param_hw_array(scsi_id, int, other, NULL, 0);
+MODULE_PARM_DESC(scsi_id, "SCSI ID of controller (default = 6)");
+
+static unsigned long addresses[] = {
+   0xc8000,
+   0xca000,
+   0xce000,
+   0xde000,
+};
+#define ADDRESS_COUNT ARRAY_SIZE(addresses)
+
+static unsigned short ports[] = { 0x140, 0x150, 0x160, 0x170 };
+#define PORT_COUNT ARRAY_SIZE(ports)
+
+static unsigned short irqs[] = { 3, 5, 10, 11, 12, 14, 15, 0 };
+
+/* This driver works *ONLY* for Future Domain cards using the TMC-1800,
+ * TMC-18C50, or TMC-18C30 chip.  This includes models TMC-1650, 1660, 1670,
+ * and 1680. These are all 16-bit cards.
+ *
+ * The following BIOS signature signatures are for boards which do *NOT*
+ * work with this driver (these TMC-8xx and TMC-9xx boards may work with the
+ * Seagate driver):
+ *
+ * FUTURE DOMAIN CORP. (C) 1986-1988 V4.0I 03/16/88
+ * FUTURE DOMAIN CORP. (C) 1986-1989 V5.0C2/14/89
+ * FUTURE DOMAIN CORP. (C) 1986-1989 V6.0A7/28/89
+ * FUTURE DOMAIN CORP. (C) 1986-1990 V6.0105/31/90
+ * FUTURE DOMAIN CORP. (C) 1986-1990 V6.0209/18/90
+ * FUTURE DOMAIN CORP. (C) 1986-1990 V7.009/18/90
+ * FUTURE DOMAIN CORP. (C) 1992 V8.00.004/02/92
+ *
+ * (The cards which do *NOT* work are all 8-bit cards -- although some of
+ * them have a 16-bit form-factor, the upper 8-bits are used only for IRQs
+ * and are *NOT* used for data. You can tell the difference by following
+ * the tracings on the circuit board -- if only the IRQ lines are involved,
+ * you have a "8-bit" card, and should *NOT* use this driver.)
+ */
+
+static struct signature signatures[] = {
+/*  1 2 3 4 5 6 */
+/* 123456789012345678901234567890123456789012345678901234567890 */
+{ "FUTURE DOMAIN CORP. (C) 1986-1990 1800-V2.07/28/89", 5, 50,  2,  0, 
0 },
+{ "FUTURE DOMAIN CORP. (C) 1986-1990 1800-V1.07/28/89", 5, 50,  2,  0, 
0 },
+{ "FUTURE DOMAIN CORP. (C) 1986-1990 1800-V2.07/28/89", 72, 50,  2,  0, 2 },
+{ "FUTURE DOMAIN CORP. (C) 1986-1990 1800-V2.0",   73, 43,  2,  0, 3 },
+{ "FUTURE DOMAIN CORP. (C) 1991 1800-V2.0.",   72, 39,  2,  0, 4 },
+{ "FUTURE DOMAIN CORP. (C) 1992 V3.00.0

Re: [RFC PATCH 1/4] fdomain: Resurrect driver (core)

2019-04-28 Thread Ondrej Zary
On Wednesday 24 April 2019 08:02:12 Christoph Hellwig wrote:
> > +static void fdomain_work(struct work_struct *work)
> > +{
> > +   struct fdomain *fd = container_of(work, struct fdomain, work);
> > +   struct Scsi_Host *sh = container_of((void *)fd, struct Scsi_Host,
> > +   hostdata);
> 
> This looks odd.  We should never need a void cast for container_of.

This cast is present in all drivers involving container_of, struct Scsi_Host 
and hostdata. hostdata in struct Scsi_Host is defined as "unsigned long 
hostdata[0]"...

-- 
Ondrej Zary


[RFC PATCH 4/4] fdomain: Resurrect driver (PCMCIA support)

2019-04-22 Thread Ondrej Zary
Future Domain PCMCIA SCSI support card support.

Currently untested.

Signed-off-by: Ondrej Zary 
---
 drivers/scsi/pcmcia/Kconfig  | 10 +
 drivers/scsi/pcmcia/Makefile |  1 +
 drivers/scsi/pcmcia/fdomain_cs.c | 89 
 3 files changed, 100 insertions(+)
 create mode 100644 drivers/scsi/pcmcia/fdomain_cs.c

diff --git a/drivers/scsi/pcmcia/Kconfig b/drivers/scsi/pcmcia/Kconfig
index 2d435f105b16..169d93f90a30 100644
--- a/drivers/scsi/pcmcia/Kconfig
+++ b/drivers/scsi/pcmcia/Kconfig
@@ -19,6 +19,16 @@ config PCMCIA_AHA152X
  To compile this driver as a module, choose M here: the
  module will be called aha152x_cs.
 
+config PCMCIA_FDOMAIN
+   tristate "Future Domain PCMCIA support"
+   select SCSI_FDOMAIN
+   help
+ Say Y here if you intend to attach this type of PCMCIA SCSI host
+ adapter to your computer.
+
+ To compile this driver as a module, choose M here: the
+ module will be called fdomain_cs.
+
 config PCMCIA_NINJA_SCSI
tristate "NinjaSCSI-3 / NinjaSCSI-32Bi (16bit) PCMCIA support"
depends on !64BIT
diff --git a/drivers/scsi/pcmcia/Makefile b/drivers/scsi/pcmcia/Makefile
index a5a24dd44e7e..02f5b44a2685 100644
--- a/drivers/scsi/pcmcia/Makefile
+++ b/drivers/scsi/pcmcia/Makefile
@@ -4,6 +4,7 @@ ccflags-y   := -I $(srctree)/drivers/scsi
 
 # 16-bit client drivers
 obj-$(CONFIG_PCMCIA_QLOGIC)+= qlogic_cs.o
+obj-$(CONFIG_PCMCIA_FDOMAIN)   += fdomain_cs.o
 obj-$(CONFIG_PCMCIA_AHA152X)   += aha152x_cs.o
 obj-$(CONFIG_PCMCIA_NINJA_SCSI)+= nsp_cs.o
 obj-$(CONFIG_PCMCIA_SYM53C500) += sym53c500_cs.o
diff --git a/drivers/scsi/pcmcia/fdomain_cs.c b/drivers/scsi/pcmcia/fdomain_cs.c
new file mode 100644
index ..eee1379ad67b
--- /dev/null
+++ b/drivers/scsi/pcmcia/fdomain_cs.c
@@ -0,0 +1,89 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MPL-1.1)
+/*
+ * Driver for Future Domain-compatible PCMCIA SCSI cards
+ * Copyright 2019 Ondrej Zary
+ *
+ * The initial developer of the original code is David A. Hinds
+ * .  Portions created by David A. Hinds
+ * are Copyright (C) 1999 David A. Hinds.  All Rights Reserved.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include "fdomain.h"
+
+MODULE_AUTHOR("Ondrej Zary, David Hinds");
+MODULE_DESCRIPTION("Future Domain PCMCIA SCSI driver");
+MODULE_LICENSE("Dual MPL/GPL");
+
+static int fdomain_config_check(struct pcmcia_device *p_dev, void *priv_data)
+{
+   p_dev->io_lines = 10;
+   p_dev->resource[0]->end = 0x10;
+   p_dev->resource[0]->flags &= ~IO_DATA_PATH_WIDTH;
+   p_dev->resource[0]->flags |= IO_DATA_PATH_WIDTH_AUTO;
+   return pcmcia_request_io(p_dev);
+}
+
+static int fdomain_probe(struct pcmcia_device *link)
+{
+   int ret;
+   struct Scsi_Host *sh;
+
+   link->config_flags |= CONF_ENABLE_IRQ | CONF_AUTO_SET_IO;
+   link->config_regs = PRESENT_OPTION;
+
+   ret = pcmcia_loop_config(link, fdomain_config_check, NULL);
+   if (ret)
+   return ret;
+
+   ret = pcmcia_enable_device(link);
+   if (ret)
+   goto fail;
+
+   sh = fdomain_create(link->resource[0]->start, link->irq, 7, 0, NULL,
+   &link->dev);
+   if (!sh) {
+   dev_err(&link->dev, "Controller initialization failed");
+   ret = -ENODEV;
+   goto fail;
+   }
+
+   link->priv = sh;
+
+   return 0;
+
+fail:
+   pcmcia_disable_device(link);
+   return ret;
+}
+
+static void fdomain_remove(struct pcmcia_device *link)
+{
+   fdomain_destroy(link->priv);
+   pcmcia_disable_device(link);
+}
+
+static const struct pcmcia_device_id fdomain_ids[] = {
+   PCMCIA_DEVICE_PROD_ID12("IBM Corp.", "SCSI PCMCIA Card", 0xe3736c88,
+   0x859cad20),
+   PCMCIA_DEVICE_PROD_ID1("SCSI PCMCIA Adapter Card", 0x8dacb57e),
+   PCMCIA_DEVICE_PROD_ID12(" SIMPLE TECHNOLOGY Corporation",
+   "SCSI PCMCIA Credit Card Controller",
+   0x182bdafe, 0xc80d106f),
+   PCMCIA_DEVICE_NULL,
+};
+MODULE_DEVICE_TABLE(pcmcia, fdomain_ids);
+
+static struct pcmcia_driver fdomain_cs_driver = {
+   .owner  = THIS_MODULE,
+   .name   = "fdomain_cs",
+   .probe  = fdomain_probe,
+   .remove = fdomain_remove,
+   .id_table   = fdomain_ids,
+};
+
+module_pcmcia_driver(fdomain_cs_driver);
-- 
Ondrej Zary



[RFC PATCH 2/4] fdomain: Resurrect driver (PCI support)

2019-04-22 Thread Ondrej Zary
Future Domain TMC-3260/AHA-2920A PCI card support.

Tested on Adaptec AHA-2920A PCI card.

Signed-off-by: Ondrej Zary 
---
 drivers/scsi/Kconfig   | 17 
 drivers/scsi/Makefile  |  1 +
 drivers/scsi/fdomain_pci.c | 68 ++
 3 files changed, 86 insertions(+)
 create mode 100644 drivers/scsi/fdomain_pci.c

diff --git a/drivers/scsi/Kconfig b/drivers/scsi/Kconfig
index 3d6b1f47cbb5..f9d058a07e2a 100644
--- a/drivers/scsi/Kconfig
+++ b/drivers/scsi/Kconfig
@@ -667,6 +667,23 @@ config SCSI_FDOMAIN
tristate
depends on SCSI
 
+config SCSI_FDOMAIN_PCI
+   tristate "Future Domain TMC-3260/AHA-2920A PCI SCSI support"
+   depends on PCI && SCSI
+   select SCSI_FDOMAIN
+   help
+ This is support for Future Domain's PCI SCSI host adapters (TMC-3260)
+ and other adapters with PCI bus based on the Future Domain chipsets
+ (Adaptec AHA-2920A).
+
+ NOTE: Newer Adaptec AHA-2920C boards use the Adaptec AIC-7850 chip
+ and should use the aic7xxx driver ("Adaptec AIC7xxx chipset SCSI
+ controller support"). This Future Domain driver works with the older
+ Adaptec AHA-2920A boards with a Future Domain chip on them.
+
+ To compile this driver as a module, choose M here: the
+ module will be called fdomain_pci.
+
 config SCSI_GDTH
tristate "Intel/ICP (former GDT SCSI Disk Array) RAID Controller 
support"
depends on PCI && SCSI
diff --git a/drivers/scsi/Makefile b/drivers/scsi/Makefile
index b8fbc6d2de54..f6cc4fbe6957 100644
--- a/drivers/scsi/Makefile
+++ b/drivers/scsi/Makefile
@@ -77,6 +77,7 @@ obj-$(CONFIG_SCSI_PM8001) += pm8001/
 obj-$(CONFIG_SCSI_ISCI)+= isci/
 obj-$(CONFIG_SCSI_IPS) += ips.o
 obj-$(CONFIG_SCSI_FDOMAIN) += fdomain.o
+obj-$(CONFIG_SCSI_FDOMAIN_PCI) += fdomain_pci.o
 obj-$(CONFIG_SCSI_GENERIC_NCR5380) += g_NCR5380.o
 obj-$(CONFIG_SCSI_QLOGIC_FAS)  += qlogicfas408.o   qlogicfas.o
 obj-$(CONFIG_PCMCIA_QLOGIC)+= qlogicfas408.o
diff --git a/drivers/scsi/fdomain_pci.c b/drivers/scsi/fdomain_pci.c
new file mode 100644
index ..381a7157c078
--- /dev/null
+++ b/drivers/scsi/fdomain_pci.c
@@ -0,0 +1,68 @@
+// SPDX-License-Identifier: GPL-2.0
+
+#include 
+#include 
+#include "fdomain.h"
+
+static int fdomain_pci_probe(struct pci_dev *pdev,
+const struct pci_device_id *d)
+{
+   int err;
+   struct Scsi_Host *sh;
+
+   err = pci_enable_device(pdev);
+   if (err)
+   goto fail;
+
+   err = pci_request_regions(pdev, "fdomain_pci");
+   if (err)
+   goto disable_device;
+
+   err = -ENODEV;
+   if (pci_resource_len(pdev, 0) == 0)
+   goto release_region;
+
+   sh = fdomain_create(pci_resource_start(pdev, 0), pdev->irq, 7, 0, NULL,
+   &pdev->dev);
+   if (!sh)
+   goto release_region;
+
+   pci_set_drvdata(pdev, sh);
+   return 0;
+
+release_region:
+   pci_release_regions(pdev);
+disable_device:
+   pci_disable_device(pdev);
+fail:
+   return err;
+}
+
+static void fdomain_pci_remove(struct pci_dev *pdev)
+{
+   struct Scsi_Host *sh = pci_get_drvdata(pdev);
+
+   fdomain_destroy(sh);
+   pci_release_regions(pdev);
+   pci_disable_device(pdev);
+}
+
+static struct pci_device_id fdomain_pci_table[] = {
+   { PCI_DEVICE(PCI_VENDOR_ID_FD, PCI_DEVICE_ID_FD_36C70) },
+   {}
+};
+MODULE_DEVICE_TABLE(pci, fdomain_pci_table);
+
+static struct pci_driver fdomain_pci_driver = {
+   .name   = "fdomain_pci",
+   .id_table   = fdomain_pci_table,
+   .probe  = fdomain_pci_probe,
+   .remove = fdomain_pci_remove,
+   .driver.pm      = FDOMAIN_PM_OPS,
+};
+
+module_pci_driver(fdomain_pci_driver);
+
+MODULE_AUTHOR("Ondrej Zary, Rickard E. Faith");
+MODULE_DESCRIPTION("Future Domain TMC-3260 PCI SCSI driver");
+MODULE_LICENSE("GPL");
-- 
Ondrej Zary



[RFC PATCH 1/4] fdomain: Resurrect driver (core)

2019-04-22 Thread Ondrej Zary
Future Domain TMC-16xx/TMC-3260 SCSI driver.

This is the core driver, common for PCI, ISA and PCMCIA cards.

Signed-off-by: Ondrej Zary 
---
 drivers/scsi/Kconfig   |   4 +
 drivers/scsi/Makefile  |   1 +
 drivers/scsi/fdomain.c | 666 +
 drivers/scsi/fdomain.h |  25 ++
 4 files changed, 696 insertions(+)
 create mode 100644 drivers/scsi/fdomain.c
 create mode 100644 drivers/scsi/fdomain.h

diff --git a/drivers/scsi/Kconfig b/drivers/scsi/Kconfig
index d528018e6fa8..3d6b1f47cbb5 100644
--- a/drivers/scsi/Kconfig
+++ b/drivers/scsi/Kconfig
@@ -663,6 +663,10 @@ config SCSI_DMX3191D
  To compile this driver as a module, choose M here: the
  module will be called dmx3191d.
 
+config SCSI_FDOMAIN
+   tristate
+   depends on SCSI
+
 config SCSI_GDTH
tristate "Intel/ICP (former GDT SCSI Disk Array) RAID Controller 
support"
depends on PCI && SCSI
diff --git a/drivers/scsi/Makefile b/drivers/scsi/Makefile
index 8826111fdf4a..b8fbc6d2de54 100644
--- a/drivers/scsi/Makefile
+++ b/drivers/scsi/Makefile
@@ -76,6 +76,7 @@ obj-$(CONFIG_SCSI_AIC94XX)+= aic94xx/
 obj-$(CONFIG_SCSI_PM8001)  += pm8001/
 obj-$(CONFIG_SCSI_ISCI)+= isci/
 obj-$(CONFIG_SCSI_IPS) += ips.o
+obj-$(CONFIG_SCSI_FDOMAIN) += fdomain.o
 obj-$(CONFIG_SCSI_GENERIC_NCR5380) += g_NCR5380.o
 obj-$(CONFIG_SCSI_QLOGIC_FAS)  += qlogicfas408.o   qlogicfas.o
 obj-$(CONFIG_PCMCIA_QLOGIC)+= qlogicfas408.o
diff --git a/drivers/scsi/fdomain.c b/drivers/scsi/fdomain.c
new file mode 100644
index ..19ae4e0bd00e
--- /dev/null
+++ b/drivers/scsi/fdomain.c
@@ -0,0 +1,666 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Driver for Future Domain TMC-16x0 and TMC-3260 SCSI host adapters
+ * Copyright 2019 Ondrej Zary
+ *
+ * Original driver by
+ * Rickard E. Faith, fa...@cs.unc.edu
+ *
+ * Future Domain BIOS versions supported for autodetect:
+ *2.0, 3.0, 3.2, 3.4 (1.0), 3.5 (2.0), 3.6, 3.61
+ * Chips supported:
+ *TMC-1800, TMC-18C50, TMC-18C30, TMC-36C70
+ * Boards supported:
+ *Future Domain TMC-1650, TMC-1660, TMC-1670, TMC-1680, TMC-1610M/MER/MEX
+ *Future Domain TMC-3260 (PCI)
+ *Quantum ISA-200S, ISA-250MG
+ *Adaptec AHA-2920A (PCI) [BUT *NOT* AHA-2920C -- use aic7xxx instead]
+ *IBM ?
+ *
+ * NOTE:
+ *
+ * The Adaptec AHA-2920C has an Adaptec AIC-7850 chip on it.
+ * Use the aic7xxx driver for this board.
+ *
+ * The Adaptec AHA-2920A has a Future Domain chip on it, so this is the right
+ * driver for that card.  Unfortunately, the boxes will probably just say
+ * "2920", so you'll have to look on the card for a Future Domain logo, or a
+ * letter after the 2920.
+ *
+ * If you have a TMC-8xx or TMC-9xx board, then this is not the driver for
+ * your board.
+ *
+ * DESCRIPTION:
+ *
+ * This is the Linux low-level SCSI driver for Future Domain TMC-1660/1680
+ * TMC-1650/1670, and TMC-3260 SCSI host adapters.  The 1650 and 1670 have a
+ * 25-pin external connector, whereas the 1660 and 1680 have a SCSI-2 50-pin
+ * high-density external connector.  The 1670 and 1680 have floppy disk
+ * controllers built in.  The TMC-3260 is a PCI bus card.
+ *
+ * Future Domain's older boards are based on the TMC-1800 chip, and this
+ * driver was originally written for a TMC-1680 board with the TMC-1800 chip.
+ * More recently, boards are being produced with the TMC-18C50 and TMC-18C30
+ * chips.
+ *
+ * Please note that the drive ordering that Future Domain implemented in BIOS
+ * versions 3.4 and 3.5 is the opposite of the order (currently) used by the
+ * rest of the SCSI industry.
+ *
+ *
+ * REFERENCES USED:
+ *
+ * "TMC-1800 SCSI Chip Specification (FDC-1800T)", Future Domain Corporation,
+ * 1990.
+ *
+ * "Technical Reference Manual: 18C50 SCSI Host Adapter Chip", Future Domain
+ * Corporation, January 1992.
+ *
+ * "LXT SCSI Products: Specifications and OEM Technical Manual (Revision
+ * B/September 1991)", Maxtor Corporation, 1991.
+ *
+ * "7213S product Manual (Revision P3)", Maxtor Corporation, 1992.
+ *
+ * "Draft Proposed American National Standard: Small Computer System
+ * Interface - 2 (SCSI-2)", Global Engineering Documents. (X3T9.2/86-109,
+ * revision 10h, October 17, 1991)
+ *
+ * Private communications, Drew Eckhardt (d...@cs.colorado.edu) and Eric
+ * Youngdale (er...@cais.com), 1992.
+ *
+ * Private communication, Tuong Le (Future Domain Engineering department),
+ * 1994. (Disk geometry computations for Future Domain BIOS version 3.4, and
+ * TMC-18C30 detection.)
+ *
+ * Hogan, Thom. The Programmer's PC Sourcebook. Microsoft Press, 1988. Page
+ * 60 (2.39: Disk Partition Table Layout).
+ *
+ * "18C30 Technical Reference Manual", Future Domain Corporation, 1993, page
+ * 6-1.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#inclu

[RFC PATCH 0/4] fdomain: Resurrect driver (modular version)

2019-04-22 Thread Ondrej Zary


Resurrect previously removed fdomain driver, in modern style.
Initialization is rewritten completely, with support for multiple cards,
no more global state variables.
Most of the code from interrupt handler is moved to a workqueue.

This is a modularized version with core separated from bus-specific drivers
(PCI, ISA and PCMCIA). Only PCI driver is tested for now. The other two could
be dropped until they get tested.

-- 
Ondrej Zary


[RFC PATCH 3/4] fdomain: Resurrect driver (ISA support)

2019-04-22 Thread Ondrej Zary
Future Domain 16xx ISA SCSI support card support.

Currently untested.

Signed-off-by: Ondrej Zary 
---
 drivers/scsi/Kconfig   |  14 +++
 drivers/scsi/Makefile  |   1 +
 drivers/scsi/fdomain_isa.c | 227 +
 3 files changed, 242 insertions(+)
 create mode 100644 drivers/scsi/fdomain_isa.c

diff --git a/drivers/scsi/Kconfig b/drivers/scsi/Kconfig
index f9d058a07e2a..2ea77dafbc00 100644
--- a/drivers/scsi/Kconfig
+++ b/drivers/scsi/Kconfig
@@ -684,6 +684,20 @@ config SCSI_FDOMAIN_PCI
  To compile this driver as a module, choose M here: the
  module will be called fdomain_pci.
 
+config SCSI_FDOMAIN_ISA
+   tristate "Future Domain 16xx ISA SCSI support"
+   depends on ISA && SCSI
+   select CHECK_SIGNATURE
+   select SCSI_FDOMAIN
+   help
+ This is support for Future Domain's 16-bit SCSI host adapters
+ (TMC-1660/1680, TMC-1650/1670, TMC-1610M/MER/MEX) and other adapters
+ with ISA bus based on the Future Domain chipsets (Quantum ISA-200S,
+ ISA-250MG; and at least one IBM board).
+
+ To compile this driver as a module, choose M here: the
+ module will be called fdomain_isa.
+
 config SCSI_GDTH
tristate "Intel/ICP (former GDT SCSI Disk Array) RAID Controller 
support"
depends on PCI && SCSI
diff --git a/drivers/scsi/Makefile b/drivers/scsi/Makefile
index f6cc4fbe6957..2e2c777d 100644
--- a/drivers/scsi/Makefile
+++ b/drivers/scsi/Makefile
@@ -78,6 +78,7 @@ obj-$(CONFIG_SCSI_ISCI)   += isci/
 obj-$(CONFIG_SCSI_IPS) += ips.o
 obj-$(CONFIG_SCSI_FDOMAIN) += fdomain.o
 obj-$(CONFIG_SCSI_FDOMAIN_PCI) += fdomain_pci.o
+obj-$(CONFIG_SCSI_FDOMAIN_ISA) += fdomain_isa.o
 obj-$(CONFIG_SCSI_GENERIC_NCR5380) += g_NCR5380.o
 obj-$(CONFIG_SCSI_QLOGIC_FAS)  += qlogicfas408.o   qlogicfas.o
 obj-$(CONFIG_PCMCIA_QLOGIC)+= qlogicfas408.o
diff --git a/drivers/scsi/fdomain_isa.c b/drivers/scsi/fdomain_isa.c
new file mode 100644
index ..9f8bf02f175f
--- /dev/null
+++ b/drivers/scsi/fdomain_isa.c
@@ -0,0 +1,227 @@
+// SPDX-License-Identifier: GPL-2.0
+
+#include 
+#include 
+#include 
+#include 
+#include "fdomain.h"
+
+#define MAXBOARDS_PARAM 4
+static int io[MAXBOARDS_PARAM] = { 0, 0, 0, 0 };
+module_param_hw_array(io, int, ioport, NULL, 0);
+MODULE_PARM_DESC(io, "base I/O address of controller (0x140, 0x150, 0x160, 
0x170)");
+
+static int irq[MAXBOARDS_PARAM] = { 0, 0, 0, 0 };
+module_param_hw_array(irq, int, irq, NULL, 0);
+MODULE_PARM_DESC(irq, "IRQ of controller (0=auto [default])");
+
+static int scsi_id[MAXBOARDS_PARAM] = { 0, 0, 0, 0 };
+module_param_hw_array(scsi_id, int, other, NULL, 0);
+MODULE_PARM_DESC(scsi_id, "SCSI ID of controller (default = 6)");
+
+static unsigned long addresses[] = {
+   0xc8000,
+   0xca000,
+   0xce000,
+   0xde000,
+};
+#define ADDRESS_COUNT ARRAY_SIZE(addresses)
+
+static unsigned short ports[] = { 0x140, 0x150, 0x160, 0x170 };
+#define PORT_COUNT ARRAY_SIZE(ports)
+
+/* This driver works *ONLY* for Future Domain cards using the TMC-1800,
+ * TMC-18C50, or TMC-18C30 chip.  This includes models TMC-1650, 1660, 1670,
+ * and 1680. These are all 16-bit cards.
+ *
+ * The following BIOS signature signatures are for boards which do *NOT*
+ * work with this driver (these TMC-8xx and TMC-9xx boards may work with the
+ * Seagate driver):
+ *
+ * FUTURE DOMAIN CORP. (C) 1986-1988 V4.0I 03/16/88
+ * FUTURE DOMAIN CORP. (C) 1986-1989 V5.0C2/14/89
+ * FUTURE DOMAIN CORP. (C) 1986-1989 V6.0A7/28/89
+ * FUTURE DOMAIN CORP. (C) 1986-1990 V6.0105/31/90
+ * FUTURE DOMAIN CORP. (C) 1986-1990 V6.0209/18/90
+ * FUTURE DOMAIN CORP. (C) 1986-1990 V7.009/18/90
+ * FUTURE DOMAIN CORP. (C) 1992 V8.00.004/02/92
+ *
+ * (The cards which do *NOT* work are all 8-bit cards -- although some of
+ * them have a 16-bit form-factor, the upper 8-bits are used only for IRQs
+ * and are *NOT* used for data. You can tell the difference by following
+ * the tracings on the circuit board -- if only the IRQ lines are involved,
+ * you have a "8-bit" card, and should *NOT* use this driver.)
+ */
+
+static struct signature signatures[] = {
+/*  1 2 3 4 5 6 */
+/* 123456789012345678901234567890123456789012345678901234567890 */
+{ "FUTURE DOMAIN CORP. (C) 1986-1990 1800-V2.07/28/89", 5, 50,  2,  0, 
0 },
+{ "FUTURE DOMAIN CORP. (C) 1986-1990 1800-V1.07/28/89", 5, 50,  2,  0, 
0 },
+{ "FUTURE DOMAIN CORP. (C) 1986-1990 1800-V2.07/28/89", 72, 50,  2,  0, 2 },
+{ "FUTURE DOMAIN CORP. (C) 1986-1990 1800-V2.0",   73, 43,  2,  0, 3 },
+{ "FUTURE DOMAIN CORP. (C) 1991 1800-V2.0.",   72, 39,  2,  0, 4 },
+{ "FUTURE DOMAIN CORP. (C) 1992 V3.00.004/02/92",   5, 44,  3,  0, 0 },
+{ "FUTURE DOMAIN TM

[RFC PATCH] fdomain: Resurrect driver

2019-04-20 Thread Ondrej Zary
Resurrect previously removed fdomain driver, in modern style.
Initialization is rewritten completely, with support for multiple cards,
no more global state variables.
Most of the code from interrupt handler is moved to a workqueue.

Tested on Adaptec AHA-2920A PCI card. ISA and PCMCIA code is untested as
I don't have the hardware.

Signed-off-by: Ondrej Zary 
---
 drivers/scsi/Kconfig   |  18 +
 drivers/scsi/Makefile  |   1 +
 drivers/scsi/fdomain.c | 992 +
 drivers/scsi/fdomain.h |   7 +
 drivers/scsi/pcmcia/Kconfig|   9 +
 drivers/scsi/pcmcia/Makefile   |   2 +
 drivers/scsi/pcmcia/fdomain_core.c |   2 +
 drivers/scsi/pcmcia/fdomain_stub.c |  89 
 8 files changed, 1120 insertions(+)
 create mode 100644 drivers/scsi/fdomain.c
 create mode 100644 drivers/scsi/fdomain.h
 create mode 100644 drivers/scsi/pcmcia/fdomain_core.c
 create mode 100644 drivers/scsi/pcmcia/fdomain_stub.c

diff --git a/drivers/scsi/Kconfig b/drivers/scsi/Kconfig
index d528018e6fa8..90950d875f2d 100644
--- a/drivers/scsi/Kconfig
+++ b/drivers/scsi/Kconfig
@@ -663,6 +663,24 @@ config SCSI_DMX3191D
  To compile this driver as a module, choose M here: the
  module will be called dmx3191d.
 
+config SCSI_FUTURE_DOMAIN
+   tristate "Future Domain 16xx SCSI/AHA-2920A support"
+   depends on (ISA || PCI) && SCSI
+   select CHECK_SIGNATURE
+   help
+ This is support for Future Domain's 16-bit SCSI host adapters
+ (TMC-1660/1680, TMC-1650/1670, TMC-3260, TMC-1610M/MER/MEX) and
+ other adapters based on the Future Domain chipsets (Quantum
+ ISA-200S, ISA-250MG; Adaptec AHA-2920A; and at least one IBM board).
+
+ NOTE: Newer Adaptec AHA-2920C boards use the Adaptec AIC-7850 chip
+ and should use the aic7xxx driver ("Adaptec AIC7xxx chipset SCSI
+ controller support"). This Future Domain driver works with the older
+ Adaptec AHA-2920A boards with a Future Domain chip on them.
+
+ To compile this driver as a module, choose M here: the
+ module will be called fdomain.
+
 config SCSI_GDTH
tristate "Intel/ICP (former GDT SCSI Disk Array) RAID Controller 
support"
depends on PCI && SCSI
diff --git a/drivers/scsi/Makefile b/drivers/scsi/Makefile
index 8826111fdf4a..a9f80770d989 100644
--- a/drivers/scsi/Makefile
+++ b/drivers/scsi/Makefile
@@ -76,6 +76,7 @@ obj-$(CONFIG_SCSI_AIC94XX)+= aic94xx/
 obj-$(CONFIG_SCSI_PM8001)  += pm8001/
 obj-$(CONFIG_SCSI_ISCI)+= isci/
 obj-$(CONFIG_SCSI_IPS) += ips.o
+obj-$(CONFIG_SCSI_FUTURE_DOMAIN)+= fdomain.o
 obj-$(CONFIG_SCSI_GENERIC_NCR5380) += g_NCR5380.o
 obj-$(CONFIG_SCSI_QLOGIC_FAS)  += qlogicfas408.o   qlogicfas.o
 obj-$(CONFIG_PCMCIA_QLOGIC)+= qlogicfas408.o
diff --git a/drivers/scsi/fdomain.c b/drivers/scsi/fdomain.c
new file mode 100644
index ..814fd1b94797
--- /dev/null
+++ b/drivers/scsi/fdomain.c
@@ -0,0 +1,992 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Driver for Future Domain TMC-16x0 and TMC-3260 SCSI host adapters
+ * Copyright 2019 Ondrej Zary
+ *
+ * Original driver by
+ * Rickard E. Faith, fa...@cs.unc.edu
+ *
+ * Future Domain BIOS versions supported for autodetect:
+ *2.0, 3.0, 3.2, 3.4 (1.0), 3.5 (2.0), 3.6, 3.61
+ * Chips supported:
+ *TMC-1800, TMC-18C50, TMC-18C30, TMC-36C70
+ * Boards supported:
+ *Future Domain TMC-1650, TMC-1660, TMC-1670, TMC-1680, TMC-1610M/MER/MEX
+ *Future Domain TMC-3260 (PCI)
+ *Quantum ISA-200S, ISA-250MG
+ *Adaptec AHA-2920A (PCI) [BUT *NOT* AHA-2920C -- use aic7xxx instead]
+ *IBM ?
+ *
+ * NOTE:
+ *
+ * The Adaptec AHA-2920C has an Adaptec AIC-7850 chip on it.
+ * Use the aic7xxx driver for this board.
+ *
+ * The Adaptec AHA-2920A has a Future Domain chip on it, so this is the right
+ * driver for that card.  Unfortunately, the boxes will probably just say
+ * "2920", so you'll have to look on the card for a Future Domain logo, or a
+ * letter after the 2920.
+ *
+ * If you have a TMC-8xx or TMC-9xx board, then this is not the driver for
+ * your board.
+ *
+ * DESCRIPTION:
+ *
+ * This is the Linux low-level SCSI driver for Future Domain TMC-1660/1680
+ * TMC-1650/1670, and TMC-3260 SCSI host adapters.  The 1650 and 1670 have a
+ * 25-pin external connector, whereas the 1660 and 1680 have a SCSI-2 50-pin
+ * high-density external connector.  The 1670 and 1680 have floppy disk
+ * controllers built in.  The TMC-3260 is a PCI bus card.
+ *
+ * Future Domain's older boards are based on the TMC-1800 chip, and this
+ * driver was originally written for a TMC-1680 board with the TMC-1800 chip.
+ * More recently, boards are being produced with the TMC-18C50 and TMC-18C30
+ * chips.
+ *
+ * Please note that the drive ordering that Future Domain implemented in BIOS
+ * versions 3.4 and 3

[RFC PATCH 3/2] fdomain: Use SCSI host private data instead of global variables

2019-04-08 Thread Ondrej Zary
Move global variables into SCSI host private data in order to support
multiple cards.

Signed-off-by: Ondrej Zary 
---
 drivers/scsi/fdomain.c | 593 +
 1 file changed, 307 insertions(+), 286 deletions(-)

diff --git a/drivers/scsi/fdomain.c b/drivers/scsi/fdomain.c
index fe9e373c27a8..83294cf6b668 100644
--- a/drivers/scsi/fdomain.c
+++ b/drivers/scsi/fdomain.c
@@ -384,29 +384,32 @@ enum out_port_type {
 
 /* .bss will zero all the static variables below */
 static int   port_base;
-static unsigned long bios_base;
-static void __iomem *bios_mem;
-static int   bios_major;
-static int   bios_minor;
-static int   PCI_bus;
-#ifdef CONFIG_PCI
-static struct pci_dev  *PCI_dev;
-#endif
-static int   Quantum;  /* Quantum board variant */
 static int   interrupt_level;
-static volatile int  in_command;
-static struct scsi_cmnd  *current_SC;
-static enum chip_typechip  = unknown;
-static int   adapter_mask;
 static int   this_id;
 static int   setup_called;
 
+struct fdomain {
+   int port_base;
+   unsigned long bios_base;
+   void __iomem *bios_mem;
+   int bios_major;
+   int bios_minor;
+   int PCI_bus;
+#ifdef CONFIG_PCI
+   struct pci_dev *PCI_dev;
+#endif
+   int Quantum;/* Quantum board variant */
+   int interrupt_level;
+   volatile int in_command;
+   struct scsi_cmnd *current_SC;
+   enum chip_type chip;
+   int adapter_mask;
+   int this_id;
 #if DEBUG_RACE
-static volatile int  in_interrupt_flag;
+   volatile int in_interrupt_flag;
 #endif
-
-static int   FIFO_Size = 0x2000; /* 8k FIFO for
-   pre-tmc18c30 chips */
+   int FIFO_Size;
+};
 
 static irqreturn_t   do_fdomain_16x0_intr( int irq, void *dev_id );
 /* Allow insmod parameters to be like LILO parameters.  For example:
@@ -518,22 +521,22 @@ static struct signature {
 
 static void print_banner( struct Scsi_Host *shpnt )
 {
-   if (!shpnt) return; /* This won't ever happen */
+   struct fdomain *fd = shost_priv(shpnt);
 
-   if (bios_major < 0 && bios_minor < 0) {
+   if (fd->bios_major < 0 && fd->bios_minor < 0) {
   printk(KERN_INFO "scsi%d:  No BIOS; using scsi id %d\n",
  shpnt->host_no, shpnt->this_id);
} else {
   printk(KERN_INFO "scsi%d:  BIOS version ", shpnt->host_no);
 
-  if (bios_major >= 0) printk("%d.", bios_major);
+  if (fd->bios_major >= 0) printk("%d.", fd->bios_major);
   else printk("?.");
 
-  if (bios_minor >= 0) printk("%d", bios_minor);
+  if (fd->bios_minor >= 0) printk("%d", fd->bios_minor);
   else printk("?.");
 
   printk( " at 0x%lx using scsi id %d\n",
- bios_base, shpnt->this_id );
+ fd->bios_base, shpnt->this_id );
}
 
/* If this driver works for later FD PCI
@@ -542,11 +545,11 @@ static void print_banner( struct Scsi_Host *shpnt )
   it's PCI it's a TMC-3260 - JTM */
printk(KERN_INFO "scsi%d:  %s chip at 0x%x irq ",
   shpnt->host_no,
-  chip == tmc1800 ? "TMC-1800" : (chip == tmc18c50 ? "TMC-18C50" : 
(chip == tmc18c30 ? (PCI_bus ? "TMC-36C70 (PCI bus)" : "TMC-18C30") : 
"Unknown")),
-  port_base);
+  fd->chip == tmc1800 ? "TMC-1800" : (fd->chip == tmc18c50 ? 
"TMC-18C50" : (fd->chip == tmc18c30 ? (fd->PCI_bus ? "TMC-36C70 (PCI bus)" : 
"TMC-18C30") : "Unknown")),
+  fd->port_base);
 
-   if (interrupt_level)
-   printk("%d", interrupt_level);
+   if (fd->interrupt_level)
+   printk("%d", fd->interrupt_level);
else
 printk("");
 
@@ -568,8 +571,7 @@ int fdomain_setup(char *str)
port_base   = ints[0] >= 1 ? ints[1] : 0;
interrupt_level = ints[0] >= 2 ? ints[2] : 0;
this_id = ints[0] >= 3 ? ints[3] : 0;
-   
-   bios_major = bios_minor = -1; /* Use geometry for BIOS version >= 3.4 */
+
++setup_called;
return 1;
 }
@@ -582,22 +584,24 @@ static void do_pause(unsigned amount) /* Pause for 
amount*10 milliseconds */
mdelay(10*amount);
 }
 
-static inline void fdomain_make_bus_idle( void )
+static inline void fdomain_make_bus_idle(struct fdomain *fd)
 {
-   outb(0, port_base + SCSI_Cntl);
-   outb(0, port_base + SCSI_Mode_Cntl);
-   if (chip == tmc18c50 || chip == tmc18c30)
-outb(0x21 | PARITY_MASK, port_base + TMC_Cntl); /* Clear

[RFC PATCH 2/2] fdomain: Fix compilation

2019-04-07 Thread Ondrej Zary
Remove usage of scsi_module.c, .use_clustering and scsi_(un)register.
This allows the driver to compile and also work (tested with PCI card).

Signed-off-by: Ondrej Zary 
---
 drivers/scsi/fdomain.c | 48 --
 drivers/scsi/pcmcia/fdomain_stub.c |  2 +-
 2 files changed, 37 insertions(+), 13 deletions(-)

diff --git a/drivers/scsi/fdomain.c b/drivers/scsi/fdomain.c
index ebbe5a3e665d..fe9e373c27a8 100644
--- a/drivers/scsi/fdomain.c
+++ b/drivers/scsi/fdomain.c
@@ -415,6 +415,7 @@ static char * fdomain = NULL;
 module_param(fdomain, charp, 0);
 
 #ifndef PCMCIA
+static struct Scsi_Host*fdomain_shost;
 
 static unsigned long addresses[] = {
0xc8000,
@@ -959,7 +960,7 @@ struct Scsi_Host *__fdomain_16x0_detect(struct 
scsi_host_template *tpnt )
 /* Print out a banner here in case we can't
get resources.  */
 
-   shpnt = scsi_register( tpnt, 0 );
+   shpnt = scsi_host_alloc( tpnt, 0 );
if(shpnt == NULL) {
release_region(port_base, 0x10);
return NULL;
@@ -1003,13 +1004,6 @@ struct Scsi_Host *__fdomain_16x0_detect(struct 
scsi_host_template *tpnt )
return NULL;
 }
 
-static int fdomain_16x0_detect(struct scsi_host_template *tpnt)
-{
-   if (fdomain)
-   fdomain_setup(fdomain);
-   return (__fdomain_16x0_detect(tpnt) != NULL);
-}
-
 static const char *fdomain_16x0_info( struct Scsi_Host *ignore )
 {
static char buffer[128];
@@ -1739,6 +1733,7 @@ static int fdomain_16x0_biosparam(struct scsi_device 
*sdev,
return 0;
 }
 
+#ifndef PCMCIA
 static int fdomain_16x0_release(struct Scsi_Host *shpnt)
 {
if (shpnt->irq)
@@ -1749,22 +1744,21 @@ static int fdomain_16x0_release(struct Scsi_Host *shpnt)
pci_dev_put(PCI_dev);
return 0;
 }
+#endif
 
 struct scsi_host_template fdomain_driver_template = {
.module = THIS_MODULE,
.name   = "fdomain",
.proc_name  = "fdomain",
-   .detect = fdomain_16x0_detect,
.info   = fdomain_16x0_info,
.queuecommand   = fdomain_16x0_queue,
.eh_abort_handler   = fdomain_16x0_abort,
.eh_host_reset_handler  = fdomain_16x0_host_reset,
.bios_param = fdomain_16x0_biosparam,
-   .release= fdomain_16x0_release,
.can_queue  = 1,
.this_id= 6,
.sg_tablesize   = 64,
-   .use_clustering = DISABLE_CLUSTERING,
+   .dma_boundary   = PAGE_SIZE - 1,
 };
 
 #ifndef PCMCIA
@@ -1778,6 +1772,36 @@ static struct pci_device_id fdomain_pci_tbl[] = {
 MODULE_DEVICE_TABLE(pci, fdomain_pci_tbl);
 #endif
 #define driver_template fdomain_driver_template
-#include "scsi_module.c"
+
+static int __init fdomain_16x0_init(void)
+{
+   int ret;
+
+   if (fdomain)
+   fdomain_setup(fdomain);
+   fdomain_shost = __fdomain_16x0_detect(&driver_template);
+   if (!fdomain_shost)
+   return -ENODEV;
+
+   ret = scsi_add_host(fdomain_shost, NULL);
+   if (ret)
+   goto fail;
+   scsi_scan_host(fdomain_shost);
+
+   return 0;
+fail:
+   scsi_remove_host(fdomain_shost);
+   return ret;
+}
+
+static void __exit fdomain_16x0_exit(void)
+{
+   scsi_remove_host(fdomain_shost);
+   fdomain_16x0_release(fdomain_shost);
+   scsi_host_put(fdomain_shost);
+}
+
+module_init(fdomain_16x0_init);
+module_exit(fdomain_16x0_exit);
 
 #endif
diff --git a/drivers/scsi/pcmcia/fdomain_stub.c 
b/drivers/scsi/pcmcia/fdomain_stub.c
index 953a792150ae..5febbb7d611b 100644
--- a/drivers/scsi/pcmcia/fdomain_stub.c
+++ b/drivers/scsi/pcmcia/fdomain_stub.c
@@ -166,7 +166,7 @@ static void fdomain_release(struct pcmcia_device *link)
 
scsi_remove_host(info->host);
pcmcia_disable_device(link);
-   scsi_unregister(info->host);
+   scsi_host_put(info->host);
 }
 
 /*====*/
-- 
Ondrej Zary



[RFC PATCH 0/2] fdomain: Resurrect driver

2019-04-07 Thread Ondrej Zary
Hello,
the removal of fdomain driver caused regressions:
https://alioth-lists.debian.net/pipermail/sane-devel/2019-January/036552.html

I've got a fdomain-based AHA-2920A card so I'll try to resurrect the driver
and then clean it up.



[RFC PATCH 1/2] fdomain: Resurrect fdomain and fdomain_cs drivers

2019-04-07 Thread Ondrej Zary
This reverts commit e184f2bf4d9f1a3c612a8c1d67e73e9cf8ab5ab9.
It does not compile but following patches will fix that.

Signed-off-by: Ondrej Zary 
---
 MAINTAINERS|6 +
 drivers/scsi/Kconfig   |   20 +
 drivers/scsi/Makefile  |1 +
 drivers/scsi/fdomain.c | 1783 
 drivers/scsi/fdomain.h |   24 +
 drivers/scsi/pcmcia/Kconfig|9 +
 drivers/scsi/pcmcia/Makefile   |2 +
 drivers/scsi/pcmcia/fdomain_core.c |2 +
 drivers/scsi/pcmcia/fdomain_stub.c |  209 +
 9 files changed, 2056 insertions(+)
 create mode 100644 drivers/scsi/fdomain.c
 create mode 100644 drivers/scsi/fdomain.h
 create mode 100644 drivers/scsi/pcmcia/fdomain_core.c
 create mode 100644 drivers/scsi/pcmcia/fdomain_stub.c

diff --git a/MAINTAINERS b/MAINTAINERS
index 2359e12e4c41..4ff767f79454 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -6416,6 +6416,12 @@ F:   tools/testing/selftests/futex/
 F: tools/perf/bench/futex*
 F: Documentation/*futex*
 
+FUTURE DOMAIN TMC-16x0 SCSI DRIVER (16-bit)
+M: Rik Faith 
+L: linux-scsi@vger.kernel.org
+S: Odd Fixes (e.g., new signatures)
+F: drivers/scsi/fdomain.*
+
 GCC PLUGINS
 M: Kees Cook 
 R: Emese Revfy 
diff --git a/drivers/scsi/Kconfig b/drivers/scsi/Kconfig
index d528018e6fa8..58690189c8cf 100644
--- a/drivers/scsi/Kconfig
+++ b/drivers/scsi/Kconfig
@@ -663,6 +663,26 @@ config SCSI_DMX3191D
  To compile this driver as a module, choose M here: the
  module will be called dmx3191d.
 
+config SCSI_FUTURE_DOMAIN
+   tristate "Future Domain 16xx SCSI/AHA-2920A support"
+   depends on (ISA || PCI) && SCSI
+   select CHECK_SIGNATURE
+   ---help---
+ This is support for Future Domain's 16-bit SCSI host adapters
+ (TMC-1660/1680, TMC-1650/1670, TMC-3260, TMC-1610M/MER/MEX) and
+ other adapters based on the Future Domain chipsets (Quantum
+ ISA-200S, ISA-250MG; Adaptec AHA-2920A; and at least one IBM board).
+ It is explained in section 3.7 of the SCSI-HOWTO, available from
+ <http://www.tldp.org/docs.html#howto>.
+
+ NOTE: Newer Adaptec AHA-2920C boards use the Adaptec AIC-7850 chip
+ and should use the aic7xxx driver ("Adaptec AIC7xxx chipset SCSI
+ controller support"). This Future Domain driver works with the older
+ Adaptec AHA-2920A boards with a Future Domain chip on them.
+
+ To compile this driver as a module, choose M here: the
+ module will be called fdomain.
+
 config SCSI_GDTH
tristate "Intel/ICP (former GDT SCSI Disk Array) RAID Controller 
support"
depends on PCI && SCSI
diff --git a/drivers/scsi/Makefile b/drivers/scsi/Makefile
index 8826111fdf4a..a9f80770d989 100644
--- a/drivers/scsi/Makefile
+++ b/drivers/scsi/Makefile
@@ -76,6 +76,7 @@ obj-$(CONFIG_SCSI_AIC94XX)+= aic94xx/
 obj-$(CONFIG_SCSI_PM8001)  += pm8001/
 obj-$(CONFIG_SCSI_ISCI)+= isci/
 obj-$(CONFIG_SCSI_IPS) += ips.o
+obj-$(CONFIG_SCSI_FUTURE_DOMAIN)+= fdomain.o
 obj-$(CONFIG_SCSI_GENERIC_NCR5380) += g_NCR5380.o
 obj-$(CONFIG_SCSI_QLOGIC_FAS)  += qlogicfas408.o   qlogicfas.o
 obj-$(CONFIG_PCMCIA_QLOGIC)+= qlogicfas408.o
diff --git a/drivers/scsi/fdomain.c b/drivers/scsi/fdomain.c
new file mode 100644
index ..ebbe5a3e665d
--- /dev/null
+++ b/drivers/scsi/fdomain.c
@@ -0,0 +1,1783 @@
+/* fdomain.c -- Future Domain TMC-16x0 SCSI driver
+ * Created: Sun May  3 18:53:19 1992 by fa...@cs.unc.edu
+ * Revised: Mon Dec 28 21:59:02 1998 by fa...@acm.org
+ * Author: Rickard E. Faith, fa...@cs.unc.edu
+ * Copyright 1992-1996, 1998 Rickard E. Faith (fa...@acm.org)
+ * Shared IRQ supported added 7/7/2001  Alan Cox 
+
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2, or (at your option) any
+ * later version.
+
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ **
+
+ SUMMARY:
+
+ Future Domain BIOS versions supported for autodetect:
+2.0, 3.0, 3.2, 3.4 (1.0), 3.5 (2.0), 3.6, 3.61
+ Chips are supported:
+TMC-1800, TMC-18C50, TMC-18C30, TMC-36C70
+ Boards supported:
+Future Domain TMC-1650, TMC-1660, TMC-1670, TMC-1680, TMC-1610M/MER/MEX
+Future Domain TMC-3260 (PCI)
+Quantum ISA-200S, ISA-250MG

Re: [PATCH] aha1542: convert to DMA mapping API

2018-11-09 Thread Ondrej Zary
On Friday 09 November 2018 16:45:54 Christoph Hellwig wrote:
> aha1542 is one of the last users of the legacy isa_*_to_bus APIs, which
> also isn't portable enough.  Convert it to the proper DMA mapping API.
> 
> Thanks to Ondrej Zary for testing and finding and fixing a crucial
> bug.
> 
> Signed-off-by: Christoph Hellwig 
> Tested-by: Ondrej Zary 
> ---
>  drivers/scsi/aha1542.c | 126 +
>  1 file changed, 91 insertions(+), 35 deletions(-)
> 
> diff --git a/drivers/scsi/aha1542.c b/drivers/scsi/aha1542.c
> index 41add33e3f1f..398fcdc6f4c9 100644
> --- a/drivers/scsi/aha1542.c
> +++ b/drivers/scsi/aha1542.c
> @@ -58,8 +58,15 @@ struct aha1542_hostdata {
>   int aha1542_last_mbi_used;
>   int aha1542_last_mbo_used;
>   struct scsi_cmnd *int_cmds[AHA1542_MAILBOXES];
> - struct mailbox mb[2 * AHA1542_MAILBOXES];
> - struct ccb ccb[AHA1542_MAILBOXES];
> + struct mailbox *mb;
> + dma_addr_t mb_handle;
> + struct ccb *ccb;
> + dma_addr_t ccb_handle;
> +};
> +
> +struct aha1542_cmd {
> + struct chain *chain;
> + dma_addr_t chain_handle;
>  };
>  
>  static inline void aha1542_intr_reset(u16 base)
> @@ -233,6 +240,21 @@ static int aha1542_test_port(struct Scsi_Host *sh)
>   return 1;
>  }
>  
> +static void aha1542_free_cmd(struct scsi_cmnd *cmd)
> +{
> + struct aha1542_cmd *acmd = scsi_cmd_priv(cmd);
> + struct device *dev = cmd->device->host->dma_dev;
> + size_t len = scsi_sg_count(cmd) * sizeof(struct chain);
> +
> + if (acmd->chain) {
> + dma_unmap_single(dev, acmd->chain_handle, len, DMA_TO_DEVICE);
> + kfree(acmd->chain);
> + }
> +
> + acmd->chain = NULL;
> + scsi_dma_unmap(cmd);
> +}
> +
>  static irqreturn_t aha1542_interrupt(int irq, void *dev_id)
>  {
>   struct Scsi_Host *sh = dev_id;
> @@ -303,7 +325,7 @@ static irqreturn_t aha1542_interrupt(int irq, void 
> *dev_id)
>   return IRQ_HANDLED;
>   };
>  
> - mbo = (scsi2int(mb[mbi].ccbptr) - (isa_virt_to_bus(&ccb[0]))) / 
> sizeof(struct ccb);
> + mbo = (scsi2int(mb[mbi].ccbptr) - aha1542->ccb_handle) / 
> sizeof(struct ccb);
>   mbistatus = mb[mbi].status;
>   mb[mbi].status = 0;
>   aha1542->aha1542_last_mbi_used = mbi;
> @@ -331,8 +353,7 @@ static irqreturn_t aha1542_interrupt(int irq, void 
> *dev_id)
>   return IRQ_HANDLED;
>   }
>   my_done = tmp_cmd->scsi_done;
> - kfree(tmp_cmd->host_scribble);
> - tmp_cmd->host_scribble = NULL;
> + aha1542_free_cmd(tmp_cmd);
>   /* Fetch the sense data, and tuck it away, in the required 
> slot.  The
>  Adaptec automatically fetches it, and there is no guarantee 
> that
>  we will still have it in the cdb when we come back */
> @@ -369,6 +390,7 @@ static irqreturn_t aha1542_interrupt(int irq, void 
> *dev_id)
>  
>  static int aha1542_queuecommand(struct Scsi_Host *sh, struct scsi_cmnd *cmd)
>  {
> + struct aha1542_cmd *acmd = scsi_cmd_priv(cmd);
>   struct aha1542_hostdata *aha1542 = shost_priv(sh);
>   u8 direction;
>   u8 target = cmd->device->id;
> @@ -378,7 +400,6 @@ static int aha1542_queuecommand(struct Scsi_Host *sh, 
> struct scsi_cmnd *cmd)
>   int mbo, sg_count;
>   struct mailbox *mb = aha1542->mb;
>   struct ccb *ccb = aha1542->ccb;
> - struct chain *cptr;
>  
>   if (*cmd->cmnd == REQUEST_SENSE) {
>   /* Don't do the command - we have the sense data already */
> @@ -398,15 +419,17 @@ static int aha1542_queuecommand(struct Scsi_Host *sh, 
> struct scsi_cmnd *cmd)
>   print_hex_dump_bytes("command: ", DUMP_PREFIX_NONE, cmd->cmnd, 
> cmd->cmd_len);
>   }
>  #endif
> - if (bufflen) {  /* allocate memory before taking host_lock */
> - sg_count = scsi_sg_count(cmd);
> - cptr = kmalloc_array(sg_count, sizeof(*cptr),
> -  GFP_KERNEL | GFP_DMA);
> - if (!cptr)
> - return SCSI_MLQUEUE_HOST_BUSY;
> - } else {
> - sg_count = 0;
> - cptr = NULL;
> + sg_count = scsi_dma_map(cmd);
> + if (sg_count) {
> + size_t len = sg_count * sizeof(struct chain);
> +
> + acmd->chain = kmalloc(len, GFP_DMA);
> + if (!acmd->chain)
> + goto out_unmap;
> + acmd->chain_ha

Re: [PATCH] aha1542: convert to DMA mapping API

2018-10-21 Thread Ondrej Zary
On Thursday 09 August 2018 07:35:33 Christoph Hellwig wrote:
> On Wed, Aug 08, 2018 at 10:30:19PM +0200, Ondrej Zary wrote:
> > Then it crashes with null-pointer dereference in aha1542_reset.
> 
> Must be the dma_unmap.  Updated patch below:
> 
> ---
> From 98a9c770430cde972923838b990b2b9cf7b95816 Mon Sep 17 00:00:00 2001
> From: Christoph Hellwig 
> Date: Thu, 2 Aug 2018 14:22:46 +0200
> Subject: aha1542: convert to DMA mapping API
> 
> aha1542 is one of the last users of the legacy isa_*_to_bus APIs, which
> also isn't portable enough.  Convert it to the proper DMA mapping API.
> 
> Signed-off-by: Christoph Hellwig 
> ---
>  drivers/scsi/aha1542.c | 126 +
>  1 file changed, 91 insertions(+), 35 deletions(-)
> 
> diff --git a/drivers/scsi/aha1542.c b/drivers/scsi/aha1542.c
> index 41add33e3f1f..d09e19dde177 100644
> --- a/drivers/scsi/aha1542.c
> +++ b/drivers/scsi/aha1542.c
> @@ -58,8 +58,15 @@ struct aha1542_hostdata {
>   int aha1542_last_mbi_used;
>   int aha1542_last_mbo_used;
>   struct scsi_cmnd *int_cmds[AHA1542_MAILBOXES];
> - struct mailbox mb[2 * AHA1542_MAILBOXES];
> - struct ccb ccb[AHA1542_MAILBOXES];
> + struct mailbox *mb;
> + dma_addr_t mb_handle;
> + struct ccb *ccb;
> + dma_addr_t ccb_handle;
> +};
> +
> +struct aha1542_cmd {
> + struct chain *chain;
> + dma_addr_t chain_handle;
>  };
>  
>  static inline void aha1542_intr_reset(u16 base)
> @@ -233,6 +240,21 @@ static int aha1542_test_port(struct Scsi_Host *sh)
>   return 1;
>  }
>  
> +static void aha1542_free_cmd(struct scsi_cmnd *cmd)
> +{
> + struct aha1542_cmd *acmd = scsi_cmd_priv(cmd);
> + struct device *dev = cmd->device->host->dma_dev;
> + size_t len = scsi_sg_count(cmd) * sizeof(struct chain);
> +
> + if (acmd->chain) {
> + dma_unmap_single(dev, acmd->chain_handle, len, DMA_TO_DEVICE);
> + kfree(acmd->chain);
> + }
> +
> + acmd->chain = NULL;
> + scsi_dma_unmap(cmd);
> +}
> +
>  static irqreturn_t aha1542_interrupt(int irq, void *dev_id)
>  {
>   struct Scsi_Host *sh = dev_id;
> @@ -303,7 +325,7 @@ static irqreturn_t aha1542_interrupt(int irq, void 
> *dev_id)
>   return IRQ_HANDLED;
>   };
>  
> - mbo = (scsi2int(mb[mbi].ccbptr) - (isa_virt_to_bus(&ccb[0]))) / 
> sizeof(struct ccb);
> + mbo = (scsi2int(mb[mbi].ccbptr) - aha1542->ccb_handle) / 
> sizeof(struct ccb);
>   mbistatus = mb[mbi].status;
>   mb[mbi].status = 0;
>   aha1542->aha1542_last_mbi_used = mbi;
> @@ -331,8 +353,7 @@ static irqreturn_t aha1542_interrupt(int irq, void 
> *dev_id)
>   return IRQ_HANDLED;
>   }
>   my_done = tmp_cmd->scsi_done;
> - kfree(tmp_cmd->host_scribble);
> - tmp_cmd->host_scribble = NULL;
> + aha1542_free_cmd(tmp_cmd);
>   /* Fetch the sense data, and tuck it away, in the required 
> slot.  The
>  Adaptec automatically fetches it, and there is no guarantee 
> that
>  we will still have it in the cdb when we come back */
> @@ -369,6 +390,7 @@ static irqreturn_t aha1542_interrupt(int irq, void 
> *dev_id)
>  
>  static int aha1542_queuecommand(struct Scsi_Host *sh, struct scsi_cmnd *cmd)
>  {
> + struct aha1542_cmd *acmd = scsi_cmd_priv(cmd);
>   struct aha1542_hostdata *aha1542 = shost_priv(sh);
>   u8 direction;
>   u8 target = cmd->device->id;
> @@ -378,7 +400,6 @@ static int aha1542_queuecommand(struct Scsi_Host *sh, 
> struct scsi_cmnd *cmd)
>   int mbo, sg_count;
>   struct mailbox *mb = aha1542->mb;
>   struct ccb *ccb = aha1542->ccb;
> - struct chain *cptr;
>  
>   if (*cmd->cmnd == REQUEST_SENSE) {
>   /* Don't do the command - we have the sense data already */
> @@ -398,15 +419,17 @@ static int aha1542_queuecommand(struct Scsi_Host *sh, 
> struct scsi_cmnd *cmd)
>   print_hex_dump_bytes("command: ", DUMP_PREFIX_NONE, cmd->cmnd, 
> cmd->cmd_len);
>   }
>  #endif
> - if (bufflen) {  /* allocate memory before taking host_lock */
> - sg_count = scsi_sg_count(cmd);
> - cptr = kmalloc_array(sg_count, sizeof(*cptr),
> -  GFP_KERNEL | GFP_DMA);
> - if (!cptr)
> - return SCSI_MLQUEUE_HOST_BUSY;
> - } else {
> - sg_count = 0;
> - cptr = NULL;
> +  

Re: dma related cleanups for wd719x

2018-10-21 Thread Ondrej Zary
On Thursday 18 October 2018 15:01:14 Christoph Hellwig wrote:
> Hi Ondrej,
> 
> can you look over this series, which cleans up a few dma-related
> bits in the wd719x driver?
 
Hello,
this patch is needed to make it work:

diff --git a/drivers/scsi/wd719x.c b/drivers/scsi/wd719x.c
index d47190f08ed6..b73e7f24a1c4 100644
--- a/drivers/scsi/wd719x.c
+++ b/drivers/scsi/wd719x.c
@@ -183,7 +183,7 @@ static void wd719x_finish_cmd(struct wd719x_scb *scb, int 
result)
list_del(&scb->list);
 
dma_unmap_single(&wd->pdev->dev, scb->phys,
-   sizeof(struct wd719x_scb), DMA_TO_DEVICE);
+   sizeof(struct wd719x_scb), DMA_BIDIRECTIONAL);
scsi_dma_unmap(cmd);
dma_unmap_single(&wd->pdev->dev, cmd->SCp.dma_handle,
 SCSI_SENSE_BUFFERSIZE, DMA_FROM_DEVICE);
@@ -209,12 +209,19 @@ static int wd719x_queuecommand(struct Scsi_Host *sh, 
struct scsi_cmnd *cmd)
/* copy the command */
memcpy(scb->CDB, cmd->cmnd, cmd->cmd_len);
 
+   /* map SCB */
+   scb->phys = dma_map_single(&wd->pdev->dev, scb, sizeof(*scb),
+  DMA_BIDIRECTIONAL);
+
+   if (dma_mapping_error(&wd->pdev->dev, scb->phys))
+   goto out_error;
+
/* map sense buffer */
scb->sense_buf_length = SCSI_SENSE_BUFFERSIZE;
cmd->SCp.dma_handle = dma_map_single(&wd->pdev->dev, cmd->sense_buffer,
SCSI_SENSE_BUFFERSIZE, DMA_FROM_DEVICE);
if (dma_mapping_error(&wd->pdev->dev, cmd->SCp.dma_handle))
-   goto out_error;
+   goto out_unmap_scb;
scb->sense_buf = cpu_to_le32(cmd->SCp.dma_handle);
 
/* request autosense */
@@ -246,11 +253,6 @@ static int wd719x_queuecommand(struct Scsi_Host *sh, 
struct scsi_cmnd *cmd)
scb->sg_list[i].length = cpu_to_le32(sg_dma_len(sg));
}
scb->SCB_options |= WD719X_SCB_FLAGS_DO_SCATTER_GATHER;
-
-   scb->phys = dma_map_single(&wd->pdev->dev, scb, sizeof(*scb),
-  DMA_TO_DEVICE);
-   if (dma_mapping_error(&wd->pdev->dev, scb->phys))
-   goto out_unmap_scsi_cmd;
} else { /* zero length */
scb->data_length = 0;
scb->data_p = 0;
@@ -274,11 +276,12 @@ static int wd719x_queuecommand(struct Scsi_Host *sh, 
struct scsi_cmnd *cmd)
spin_unlock_irqrestore(wd->sh->host_lock, flags);
return 0;
 
-out_unmap_scsi_cmd:
-   scsi_dma_unmap(cmd);
 out_unmap_sense:
dma_unmap_single(&wd->pdev->dev, cmd->SCp.dma_handle,
 SCSI_SENSE_BUFFERSIZE, DMA_FROM_DEVICE);
+out_unmap_scb:
+   dma_unmap_single(&wd->pdev->dev, scb->phys, sizeof(*scb),
+DMA_BIDIRECTIONAL);
 out_error:
cmd->result = DID_ERROR << 16;
cmd->scsi_done(cmd);


-- 
Ondrej Zary


Re: dma related cleanups for wd719x

2018-10-19 Thread Ondrej Zary
On Thursday 18 October 2018 15:01:14 Christoph Hellwig wrote:
> Hi Ondrej,
> 
> can you look over this series, which cleans up a few dma-related
> bits in the wd719x driver?
> 

This makes it work a bit (can detect drive and read partitions) but it hangs
completely after hdparm -t.

diff --git a/drivers/scsi/wd719x.c b/drivers/scsi/wd719x.c
index d47190f08ed6..55a7a542e653 100644
--- a/drivers/scsi/wd719x.c
+++ b/drivers/scsi/wd719x.c
@@ -183,7 +183,7 @@ static void wd719x_finish_cmd(struct wd719x_scb *scb, int 
result)
list_del(&scb->list);
 
dma_unmap_single(&wd->pdev->dev, scb->phys,
-   sizeof(struct wd719x_scb), DMA_TO_DEVICE);
+   sizeof(struct wd719x_scb), DMA_BIDIRECTIONAL);
scsi_dma_unmap(cmd);
dma_unmap_single(&wd->pdev->dev, cmd->SCp.dma_handle,
 SCSI_SENSE_BUFFERSIZE, DMA_FROM_DEVICE);
@@ -236,6 +236,12 @@ static int wd719x_queuecommand(struct Scsi_Host *sh, 
struct scsi_cmnd *cmd)
if (count_sg) {
struct scatterlist *sg;
 
+   scb->phys = dma_map_single(&wd->pdev->dev, scb, sizeof(*scb),
+  DMA_BIDIRECTIONAL);
+
+   if (dma_mapping_error(&wd->pdev->dev, scb->phys))
+   goto out_unmap_scsi_cmd;
+
scb->data_length = cpu_to_le32(count_sg *
   sizeof(struct wd719x_sglist));
scb->data_p = cpu_to_le32(scb->phys +
@@ -246,11 +252,6 @@ static int wd719x_queuecommand(struct Scsi_Host *sh, 
struct scsi_cmnd *cmd)
scb->sg_list[i].length = cpu_to_le32(sg_dma_len(sg));
}
scb->SCB_options |= WD719X_SCB_FLAGS_DO_SCATTER_GATHER;
-
-   scb->phys = dma_map_single(&wd->pdev->dev, scb, sizeof(*scb),
-  DMA_TO_DEVICE);
-   if (dma_mapping_error(&wd->pdev->dev, scb->phys))
-   goto out_unmap_scsi_cmd;
    } else { /* zero length */
scb->data_length = 0;
scb->data_p = 0;



-- 
Ondrej Zary


Re: bioset changes in 4.18 broke aha1542

2018-10-18 Thread Ondrej Zary
On Thursday 18 October 2018 22:28:35 Jens Axboe wrote:
> On 10/18/18 2:22 PM, Ondrej Zary wrote:
> > On Thursday 18 October 2018 22:10:31 Jens Axboe wrote:
> >> On 10/18/18 2:04 PM, Ondrej Zary wrote:
> >>> On Thursday 18 October 2018 21:59:09 Jens Axboe wrote:
> >>>> On 10/18/18 1:55 PM, Ondrej Zary wrote:
> >>>>> On Thursday 18 October 2018 20:58:57 Jens Axboe wrote:
> >>>>>> On 10/18/18 12:34 PM, Ondrej Zary wrote:
> >>>>>>> Hello,
> >>>>>>> aha1542 works fine in 4.17 but crashes in 4.18. It's hard to bisect 
> >>>>>>> because
> >>>>>>> of many commits that don't compile.
> >>>>>>> # only skipped commits left to test
> >>>>>>> # possible first bad commit: 
> >>>>>>> [52190f8abe7f2bf2b4e5f9760cbcc1427ca2136b] fs: convert block_dev.c to 
> >>>>>>> bioset_init()
> >>>>>>> # possible first bad commit: 
> >>>>>>> [a47a28b74a5c7c27bf621276b85ad6c124651236] target: convert to 
> >>>>>>> bioset_init()/mempool_init()
> >>>>>>> # possible first bad commit: 
> >>>>>>> [6f1c819c219f7841079f0f43ab62727a55b0d849] dm: convert to 
> >>>>>>> bioset_init()/mempool_init()
> >>>>>>> # possible first bad commit: 
> >>>>>>> [afeee514ce7f4cab605beedd03be71ebaf0c5fc8] md: convert to 
> >>>>>>> bioset_init()/mempool_init()
> >>>>>>> # possible first bad commit: 
> >>>>>>> [d19936a26658a7a53edd5619d631ee2c2c3151a2] bcache: convert to 
> >>>>>>> bioset_init()/mempool_init()
> >>>>>>> # possible first bad commit: 
> >>>>>>> [b906bbb6997785d9ea0bd3f5585537afa6257c43] lightnvm: convert to 
> >>>>>>> bioset_init()/mempool_init()
> >>>>>>>
> >>>>>>> Testing manually, a47a28b74a5c7c27bf621276b85ad6c124651236 works.
> >>>>>>> 52190f8abe7f2bf2b4e5f9760cbcc1427ca2136b does not compile
> >>>>>>> 8ac9f7c1fd1d342e82ddf078425423b050652ba0 does not compile
> >>>>>>> e292d7bc63c8f2adb3dfda27910e805f1b6557f9 does not compile
> >>>>>>> dad08527525f9a8ac9c7f278864c65f94bc5e9b3 does not compile
> >>>>>>> 943cf9f3ca16133dbd00f9a4cbfea46512fcb0e8 works
> >>>>>>> ..
> >>>>>>> fedc3abe7bd2dcc4c80bcf3cff8708a3908d8219 works
> >>>>>>> 04c4950d5b373ba712d928592e05e73510785bca crashes
> >>>>>>
> >>>>>> It looks like the ISA bioset pool isn't being initialized. You should
> >>>>>> have messages like this in your dmesg:
> >>>>>>
> >>>>>> isa pool size: 16 pages
> >>>>>>
> >>>>>> (which you do), but also something on the bioset section. Do you have
> >>>>>> this one:
> >>>>>>
> >>>>>> pool size: 64 pages
> >>>>>>
> >>>>>> as well?
> >>>>>>
> >>>>>
> >>>>> No, it's not there.
> >>>>
> >>>> Can you attach your .config? I'm guessing CONFIG_HIGHMEM* isn't set.
> >>>>
> >>>
> >>> It is.
> >>
> >> Puzzled... Does this work?
> >>
> >>
> >> diff --git a/block/bounce.c b/block/bounce.c
> >> index b30071ac4ec6..49564a1bfd22 100644
> >> --- a/block/bounce.c
> >> +++ b/block/bounce.c
> >> @@ -35,10 +35,6 @@ static mempool_t page_pool, isa_page_pool;
> >>  static __init int init_emergency_pool(void)
> >>  {
> >>int ret;
> >> -#if defined(CONFIG_HIGHMEM) && !defined(CONFIG_MEMORY_HOTPLUG)
> >> -  if (max_pfn <= max_low_pfn)
> >> -  return 0;
> >> -#endif
> >>  
> >>ret = mempool_init_page_pool(&page_pool, POOL_SIZE, 0);
> >>BUG_ON(ret);
> >>
> > 
> > Yes, it does! 
> > bounce: pool size: 64 pages
> > and aha1542 works.
> > 
> > Also added printks for pfn:
> > max_pfn=65520, max_low_pfn=65520
> 
> This should be a better fix, though I'm still puzzled why we need
> it now. Can you test this one?
> 
> 
> diff --git a/block/bounce.c b/

Re: bioset changes in 4.18 broke aha1542

2018-10-18 Thread Ondrej Zary
On Thursday 18 October 2018 22:10:31 Jens Axboe wrote:
> On 10/18/18 2:04 PM, Ondrej Zary wrote:
> > On Thursday 18 October 2018 21:59:09 Jens Axboe wrote:
> >> On 10/18/18 1:55 PM, Ondrej Zary wrote:
> >>> On Thursday 18 October 2018 20:58:57 Jens Axboe wrote:
> >>>> On 10/18/18 12:34 PM, Ondrej Zary wrote:
> >>>>> Hello,
> >>>>> aha1542 works fine in 4.17 but crashes in 4.18. It's hard to bisect 
> >>>>> because
> >>>>> of many commits that don't compile.
> >>>>> # only skipped commits left to test
> >>>>> # possible first bad commit: [52190f8abe7f2bf2b4e5f9760cbcc1427ca2136b] 
> >>>>> fs: convert block_dev.c to bioset_init()
> >>>>> # possible first bad commit: [a47a28b74a5c7c27bf621276b85ad6c124651236] 
> >>>>> target: convert to bioset_init()/mempool_init()
> >>>>> # possible first bad commit: [6f1c819c219f7841079f0f43ab62727a55b0d849] 
> >>>>> dm: convert to bioset_init()/mempool_init()
> >>>>> # possible first bad commit: [afeee514ce7f4cab605beedd03be71ebaf0c5fc8] 
> >>>>> md: convert to bioset_init()/mempool_init()
> >>>>> # possible first bad commit: [d19936a26658a7a53edd5619d631ee2c2c3151a2] 
> >>>>> bcache: convert to bioset_init()/mempool_init()
> >>>>> # possible first bad commit: [b906bbb6997785d9ea0bd3f5585537afa6257c43] 
> >>>>> lightnvm: convert to bioset_init()/mempool_init()
> >>>>>
> >>>>> Testing manually, a47a28b74a5c7c27bf621276b85ad6c124651236 works.
> >>>>> 52190f8abe7f2bf2b4e5f9760cbcc1427ca2136b does not compile
> >>>>> 8ac9f7c1fd1d342e82ddf078425423b050652ba0 does not compile
> >>>>> e292d7bc63c8f2adb3dfda27910e805f1b6557f9 does not compile
> >>>>> dad08527525f9a8ac9c7f278864c65f94bc5e9b3 does not compile
> >>>>> 943cf9f3ca16133dbd00f9a4cbfea46512fcb0e8 works
> >>>>> ..
> >>>>> fedc3abe7bd2dcc4c80bcf3cff8708a3908d8219 works
> >>>>> 04c4950d5b373ba712d928592e05e73510785bca crashes
> >>>>
> >>>> It looks like the ISA bioset pool isn't being initialized. You should
> >>>> have messages like this in your dmesg:
> >>>>
> >>>> isa pool size: 16 pages
> >>>>
> >>>> (which you do), but also something on the bioset section. Do you have
> >>>> this one:
> >>>>
> >>>> pool size: 64 pages
> >>>>
> >>>> as well?
> >>>>
> >>>
> >>> No, it's not there.
> >>
> >> Can you attach your .config? I'm guessing CONFIG_HIGHMEM* isn't set.
> >>
> > 
> > It is.
> 
> Puzzled... Does this work?
> 
> 
> diff --git a/block/bounce.c b/block/bounce.c
> index b30071ac4ec6..49564a1bfd22 100644
> --- a/block/bounce.c
> +++ b/block/bounce.c
> @@ -35,10 +35,6 @@ static mempool_t page_pool, isa_page_pool;
>  static __init int init_emergency_pool(void)
>  {
>   int ret;
> -#if defined(CONFIG_HIGHMEM) && !defined(CONFIG_MEMORY_HOTPLUG)
> - if (max_pfn <= max_low_pfn)
> - return 0;
> -#endif
>  
>   ret = mempool_init_page_pool(&page_pool, POOL_SIZE, 0);
>   BUG_ON(ret);
> 

Yes, it does! 
bounce: pool size: 64 pages
and aha1542 works.

Also added printks for pfn:
max_pfn=65520, max_low_pfn=65520

-- 
Ondrej Zary


Re: bioset changes in 4.18 broke aha1542

2018-10-18 Thread Ondrej Zary
On Thursday 18 October 2018 21:59:09 Jens Axboe wrote:
> On 10/18/18 1:55 PM, Ondrej Zary wrote:
> > On Thursday 18 October 2018 20:58:57 Jens Axboe wrote:
> >> On 10/18/18 12:34 PM, Ondrej Zary wrote:
> >>> Hello,
> >>> aha1542 works fine in 4.17 but crashes in 4.18. It's hard to bisect 
> >>> because
> >>> of many commits that don't compile.
> >>> # only skipped commits left to test
> >>> # possible first bad commit: [52190f8abe7f2bf2b4e5f9760cbcc1427ca2136b] 
> >>> fs: convert block_dev.c to bioset_init()
> >>> # possible first bad commit: [a47a28b74a5c7c27bf621276b85ad6c124651236] 
> >>> target: convert to bioset_init()/mempool_init()
> >>> # possible first bad commit: [6f1c819c219f7841079f0f43ab62727a55b0d849] 
> >>> dm: convert to bioset_init()/mempool_init()
> >>> # possible first bad commit: [afeee514ce7f4cab605beedd03be71ebaf0c5fc8] 
> >>> md: convert to bioset_init()/mempool_init()
> >>> # possible first bad commit: [d19936a26658a7a53edd5619d631ee2c2c3151a2] 
> >>> bcache: convert to bioset_init()/mempool_init()
> >>> # possible first bad commit: [b906bbb6997785d9ea0bd3f5585537afa6257c43] 
> >>> lightnvm: convert to bioset_init()/mempool_init()
> >>>
> >>> Testing manually, a47a28b74a5c7c27bf621276b85ad6c124651236 works.
> >>> 52190f8abe7f2bf2b4e5f9760cbcc1427ca2136b does not compile
> >>> 8ac9f7c1fd1d342e82ddf078425423b050652ba0 does not compile
> >>> e292d7bc63c8f2adb3dfda27910e805f1b6557f9 does not compile
> >>> dad08527525f9a8ac9c7f278864c65f94bc5e9b3 does not compile
> >>> 943cf9f3ca16133dbd00f9a4cbfea46512fcb0e8 works
> >>> ..
> >>> fedc3abe7bd2dcc4c80bcf3cff8708a3908d8219 works
> >>> 04c4950d5b373ba712d928592e05e73510785bca crashes
> >>
> >> It looks like the ISA bioset pool isn't being initialized. You should
> >> have messages like this in your dmesg:
> >>
> >> isa pool size: 16 pages
> >>
> >> (which you do), but also something on the bioset section. Do you have
> >> this one:
> >>
> >> pool size: 64 pages
> >>
> >> as well?
> >>
> > 
> > No, it's not there.
> 
> Can you attach your .config? I'm guessing CONFIG_HIGHMEM* isn't set.
> 

It is.


-- 
Ondrej Zary
#
# Automatically generated file; DO NOT EDIT.
# Linux/x86 4.19.0-rc7 Kernel Configuration
#

#
# Compiler: gcc (Debian 6.3.0-18+deb9u1) 6.3.0 20170516
#
CONFIG_CC_IS_GCC=y
CONFIG_GCC_VERSION=60300
CONFIG_CLANG_VERSION=0
CONFIG_IRQ_WORK=y
CONFIG_BUILDTIME_EXTABLE_SORT=y
CONFIG_THREAD_INFO_IN_TASK=y

#
# General setup
#
CONFIG_INIT_ENV_ARG_LIMIT=32
# CONFIG_COMPILE_TEST is not set
CONFIG_LOCALVERSION=""
# CONFIG_LOCALVERSION_AUTO is not set
CONFIG_BUILD_SALT=""
CONFIG_HAVE_KERNEL_GZIP=y
CONFIG_HAVE_KERNEL_BZIP2=y
CONFIG_HAVE_KERNEL_LZMA=y
CONFIG_HAVE_KERNEL_XZ=y
CONFIG_HAVE_KERNEL_LZO=y
CONFIG_HAVE_KERNEL_LZ4=y
CONFIG_KERNEL_GZIP=y
# CONFIG_KERNEL_BZIP2 is not set
# CONFIG_KERNEL_LZMA is not set
# CONFIG_KERNEL_XZ is not set
# CONFIG_KERNEL_LZO is not set
# CONFIG_KERNEL_LZ4 is not set
CONFIG_DEFAULT_HOSTNAME="(none)"
CONFIG_SWAP=y
CONFIG_SYSVIPC=y
CONFIG_SYSVIPC_SYSCTL=y
# CONFIG_POSIX_MQUEUE is not set
CONFIG_CROSS_MEMORY_ATTACH=y
CONFIG_USELIB=y
# CONFIG_AUDIT is not set
CONFIG_HAVE_ARCH_AUDITSYSCALL=y

#
# IRQ subsystem
#
CONFIG_GENERIC_IRQ_PROBE=y
CONFIG_GENERIC_IRQ_SHOW=y
CONFIG_GENERIC_IRQ_EFFECTIVE_AFF_MASK=y
CONFIG_GENERIC_PENDING_IRQ=y
CONFIG_GENERIC_IRQ_MIGRATION=y
CONFIG_IRQ_DOMAIN=y
CONFIG_IRQ_DOMAIN_HIERARCHY=y
CONFIG_GENERIC_MSI_IRQ=y
CONFIG_GENERIC_MSI_IRQ_DOMAIN=y
CONFIG_GENERIC_IRQ_MATRIX_ALLOCATOR=y
CONFIG_GENERIC_IRQ_RESERVATION_MODE=y
CONFIG_IRQ_FORCED_THREADING=y
CONFIG_SPARSE_IRQ=y
# CONFIG_GENERIC_IRQ_DEBUGFS is not set
CONFIG_CLOCKSOURCE_WATCHDOG=y
CONFIG_ARCH_CLOCKSOURCE_DATA=y
CONFIG_CLOCKSOURCE_VALIDATE_LAST_CYCLE=y
CONFIG_GENERIC_TIME_VSYSCALL=y
CONFIG_GENERIC_CLOCKEVENTS=y
CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y
CONFIG_GENERIC_CLOCKEVENTS_MIN_ADJUST=y
CONFIG_GENERIC_CMOS_UPDATE=y

#
# Timers subsystem
#
CONFIG_TICK_ONESHOT=y
CONFIG_NO_HZ_COMMON=y
# CONFIG_HZ_PERIODIC is not set
CONFIG_NO_HZ_IDLE=y
CONFIG_NO_HZ=y
CONFIG_HIGH_RES_TIMERS=y
# CONFIG_PREEMPT_NONE is not set
CONFIG_PREEMPT_VOLUNTARY=y
# CONFIG_PREEMPT is not set

#
# CPU/Task time and stats accounting
#
CONFIG_TICK_CPU_ACCOUNTING=y
# CONFIG_IRQ_TIME_ACCOUNTING is not set
CONFIG_BSD_PROCESS_ACCT=y
CONFIG_BSD_PROCESS_ACCT_V3=y
CONFIG_TASKSTATS=y
CONFIG_TASK_DELAY_ACCT=y
CONFIG_TASK_XACCT=y
CONFIG_TASK_IO_ACCOUNTING=y
# CONFIG_CPU_ISOLATION is not set

#
# RCU Subsystem
#
CONFIG_TREE_RCU=y
# CONFIG_RCU_EXPERT is 

Re: bioset changes in 4.18 broke aha1542

2018-10-18 Thread Ondrej Zary
On Thursday 18 October 2018 20:58:57 Jens Axboe wrote:
> On 10/18/18 12:34 PM, Ondrej Zary wrote:
> > Hello,
> > aha1542 works fine in 4.17 but crashes in 4.18. It's hard to bisect because
> > of many commits that don't compile.
> > # only skipped commits left to test
> > # possible first bad commit: [52190f8abe7f2bf2b4e5f9760cbcc1427ca2136b] fs: 
> > convert block_dev.c to bioset_init()
> > # possible first bad commit: [a47a28b74a5c7c27bf621276b85ad6c124651236] 
> > target: convert to bioset_init()/mempool_init()
> > # possible first bad commit: [6f1c819c219f7841079f0f43ab62727a55b0d849] dm: 
> > convert to bioset_init()/mempool_init()
> > # possible first bad commit: [afeee514ce7f4cab605beedd03be71ebaf0c5fc8] md: 
> > convert to bioset_init()/mempool_init()
> > # possible first bad commit: [d19936a26658a7a53edd5619d631ee2c2c3151a2] 
> > bcache: convert to bioset_init()/mempool_init()
> > # possible first bad commit: [b906bbb6997785d9ea0bd3f5585537afa6257c43] 
> > lightnvm: convert to bioset_init()/mempool_init()
> > 
> > Testing manually, a47a28b74a5c7c27bf621276b85ad6c124651236 works.
> > 52190f8abe7f2bf2b4e5f9760cbcc1427ca2136b does not compile
> > 8ac9f7c1fd1d342e82ddf078425423b050652ba0 does not compile
> > e292d7bc63c8f2adb3dfda27910e805f1b6557f9 does not compile
> > dad08527525f9a8ac9c7f278864c65f94bc5e9b3 does not compile
> > 943cf9f3ca16133dbd00f9a4cbfea46512fcb0e8 works
> > ..
> > fedc3abe7bd2dcc4c80bcf3cff8708a3908d8219 works
> > 04c4950d5b373ba712d928592e05e73510785bca crashes
> 
> It looks like the ISA bioset pool isn't being initialized. You should
> have messages like this in your dmesg:
> 
> isa pool size: 16 pages
> 
> (which you do), but also something on the bioset section. Do you have
> this one:
> 
> pool size: 64 pages
> 
> as well?
> 

No, it's not there.

-- 
Ondrej Zary


Re: dma related cleanups for wd719x

2018-10-18 Thread Ondrej Zary
On Thursday 18 October 2018 15:01:14 Christoph Hellwig wrote:
> Hi Ondrej,
> 
> can you look over this series, which cleans up a few dma-related
> bits in the wd719x driver?
> 

Looks nice but does not work. The first patch works, but the 2nd one causes
hang on modprobe:
[  408.350359] wd719x :00:0c.0: RISC initialized with firmware version 03.10
[  408.949225] wd719x :00:0c.0: WD7193 at I/O 0xe800, IRQ 5, SCSI ID 7
[  408.954450] scsi host2: Western Digital 719x
[  409.263961] wd719x :00:0c.0: invalid SCSI phase
[  409.297203] wd719x :00:0c.0: invalid SCSI phase
[  409.325714] scsi 2:0:1:0: Direct-Access QUANTUM  LP240S GM240S01X 4.6  
PQ: 0 ANSI: 2 CCS
[  409.346106] wd719x :00:0c.0: invalid SCSI phase
[  409.380731] wd719x :00:0c.0: invalid SCSI phase
[  410.748579] sd 2:0:1:0: Attached scsi generic sg1 type 0


-- 
Ondrej Zary


bioset changes in 4.18 broke aha1542

2018-10-18 Thread Ondrej Zary
8b 4d e8 64 a1 9c 56 74 c7 83 b8 1c 04 00
[   86.020095] ---[ end trace f40f2545ef2bd465 ]---
[   86.259982] BUG: unable to handle kernel NULL pointer dereference at 004c
[   86.263681] *pde = 
[   86.263681] Oops:  [#1] SMP
[   86.263681] Modules linked in: aha1542 i2c_dev nouveau psmouse serio_raw 
8139cp sg wmi hwmon ttm parport_pc parport intel_agp
[   86.263681] CPU: 0 PID: 50 Comm: kworker/u2:1 Tainted: GW 
4.17.0-rc4+ #288
[   86.263681] Hardware name:  /i440ZX-W977TF, BIOS 4.51 PG 07/12/00
[   86.263681] Workqueue: events_unbound async_run_entry_fn
[   86.263681] EIP: blk_queue_bounce+0x179/0x25c
[   86.263681] EFLAGS: 00010286 CPU: 0
[   86.263681] EAX:  EBX: 0001 ECX: c77948a0 EDX: 0001
[   86.263681] ESI: 0001 EDI: 0002 EBP: cf985c2c ESP: cf985be8
[   86.263681]  DS: 007b ES: 007b FS: 00d8 GS: 00e0 SS: 0068
[   86.263681] CR0: 80050033 CR2: 004c CR3: 0c711000 CR4: 0290
[   86.263681] Call Trace:
[   86.263681]  blk_mq_make_request+0x5a/0x295
[   86.263681]  ? blk_mq_try_issue_directly+0x8b/0x8b
[   86.263681]  generic_make_request+0x184/0x246
[   86.263681]  ? alloc_buffer_head+0x13/0x49
[   86.263681]  submit_bio+0xd9/0xf1
[   86.263681]  ? bio_alloc_bioset+0xe1/0x185
[   86.263681]  ? alloc_page_buffers+0x6a/0x8a
[   86.263681]  ? guard_bio_eod+0x2c/0xae
[   86.263681]  submit_bh_wbc.isra.45+0x109/0x113
[   86.263681]  submit_bh+0xa/0xc
[   86.263681]  block_read_full_page+0x1be/0x1df
[   86.263681]  ? bd_may_claim+0x35/0x35
[   86.263681]  ? add_to_page_cache_lru+0x94/0xaf
[   86.263681]  blkdev_readpage+0xf/0x11
[   86.263681]  do_read_cache_page+0x75/0x118
[   86.263681]  ? blkdev_writepages+0xa/0xa
[   86.263681]  ? blkdev_writepages+0xa/0xa
[   86.263681]  read_cache_page+0xe/0x10
[   86.263681]  read_dev_sector+0x23/0x73
[   86.263681]  adfspart_check_ICS+0x3c/0x1c6
[   86.263681]  ? vsnprintf+0x8a/0x323
[   86.263681]  ? snprintf+0x15/0x17
[   86.263681]  check_partition+0xe3/0x16a
[   86.263681]  rescan_partitions+0x7d/0x33e
[   86.263681]  ? down_write+0xb/0x2c
[   86.263681]  ? bd_set_size+0x3e/0x6f
[   86.263681]  __blkdev_get+0x1b0/0x38a
[   86.263681]  ? get_nr_inodes_unused+0x25/0x3b
[   86.263681]  blkdev_get+0x8b/0x243
[   86.263681]  ? wake_up_bit+0x14/0x17
[   86.263681]  ? put_device+0xf/0x11
[   86.263681]  ? disk_put_part+0xf/0x11
[   86.263681]  __device_add_disk+0x338/0x36a
[   86.263681]  device_add_disk+0xd/0xf
[   86.263681]  sd_probe_async+0xf1/0x178
[   86.263681]  ? sd_revalidate_disk+0x1476/0x1476
[   86.263681]  async_run_entry_fn+0x33/0xb7
[   86.263681]  process_one_work+0xed/0x17e
[   86.263681]  worker_thread+0x168/0x1fb
[   86.263681]  kthread+0xcc/0xce
[   86.263681]  ? rescuer_thread+0x219/0x219
[   86.263681]  ? kthread_cancel_delayed_work_sync+0xf/0xf
[   86.263681]  ret_from_fork+0x2e/0x38
[   86.263681] Code: d4 8b 00 e8 8a ac fe ff 8b 45 d4 89 18 58 b9 a0 48 79 c7 
8b 45 c0 ba 00 00 40 01 83 e0 01 89 45 c0 8b 45 d4 8b 00 e8 81 6e fe ff <8b> 58 
4c 89 45 d0 8b 45 d0 0f b7 40 44 39 45 cc 73 62 8b 33 8b
[   86.263681] EIP: blk_queue_bounce+0x179/0x25c SS:ESP: 0068:cf985be8
[   86.263681] CR2: 004c
[   86.263681] ---[ end trace f40f2545ef2bd466 ]---


-- 
Ondrej Zary


Re: [PATCH] aha1542: convert to DMA mapping API

2018-08-09 Thread Ondrej Zary
On Thursday 09 August 2018 07:35:33 Christoph Hellwig wrote:
> On Wed, Aug 08, 2018 at 10:30:19PM +0200, Ondrej Zary wrote:
> > Then it crashes with null-pointer dereference in aha1542_reset.
>
> Must be the dma_unmap.  Updated patch below:

No change in behavior, unfortunately. The crash is probably just a result of 
the bad things that happen before, starting with:
scsi host2: Unexpected interrupt

-- 
Ondrej Zary


Re: [PATCH] aha1542: convert to DMA mapping API

2018-08-08 Thread Ondrej Zary
On Wednesday 08 August 2018 18:35:13 Christoph Hellwig wrote:
> On Wed, Aug 08, 2018 at 06:26:25PM +0200, Ondrej Zary wrote:
> > Looks like you attached wrong file (same as the previous one).
>
> This should be better:
>
> ---
> From afa1c18bd98168fb690d905fc84a2db6f0d617b6 Mon Sep 17 00:00:00 2001
> From: Christoph Hellwig 
> Date: Thu, 2 Aug 2018 14:22:46 +0200
> Subject: aha1542: convert to DMA mapping API

It's better but still not working:
[ 1647.365259] scsi host2: Adaptec AHA-1542 (SCSI-ID 7) at IO 0x330, IRQ 11, 
DMA 7
[ 1647.441220] scsi host2: Adaptec 1542
[ 1647.453163] bounce: isa pool size: 16 pages
[ 1647.976008] scsi host2: Unexpected interrupt
[ 1647.979955] scsi host2: tarstat=0, hastat=11 idlun=0 ccb#=0
[ 1661.503064] systemd-logind[1788]: Failed to start user service, ignoring: 
Unknown unit: user@0.service
[ 1661.626254] systemd-logind[1788]: New session c2 of user root.
[ 1669.112324] scsi 2:0:1:0: tag#0 Trying device reset for target
[ 1669.121544] scsi 2:0:1:0: tag#0 Trying device reset for target
[ 1669.129428] scsi host2: Sent BUS RESET to scsi host 2
[ 1669.375367] scsi host2: Unexpected interrupt
[ 1669.379061] scsi host2: tarstat=0, hastat=11 idlun=0 ccb#=0
[ 1679.588276] scsi 2:0:1:0: tag#0 Trying device reset for target
[ 1679.596179] scsi host2: Sent BUS RESET to scsi host 2
[ 1689.828278] scsi 2:0:1:0: tag#0 Trying device reset for target
[ 1689.832302] scsi 2:0:1:0: Device offlined - not ready after error recovery
[ 1690.331351] scsi host2: Unexpected interrupt
[ 1690.335275] scsi host2: tarstat=0, hastat=0 idlun=20 ccb#=0

Then it crashes with null-pointer dereference in aha1542_reset.

-- 
Ondrej Zary


Re: [PATCH] aha1542: convert to DMA mapping API

2018-08-08 Thread Ondrej Zary
On Wednesday 08 August 2018 11:14:33 Christoph Hellwig wrote:
> On Tue, Aug 07, 2018 at 07:30:17PM +0200, Ondrej Zary wrote:
> > On Tuesday 07 August 2018 09:29:59 Christoph Hellwig wrote:
> > > Looks like the dma allocation is too late.  Updated version below:
> > >
> > > ...
> >
> > Crashes a bit later now:
>
> Next try:
>
> ---
> From 9dd7a3eb89d1cc72c001daeb80e44de7c5fb5b00 Mon Sep 17 00:00:00 2001
> From: Christoph Hellwig 
> Date: Thu, 2 Aug 2018 14:22:46 +0200
> Subject: aha1542: convert to DMA mapping API

Looks like you attached wrong file (same as the previous one).

-- 
Ondrej Zary


Re: [PATCH] aha1542: convert to DMA mapping API

2018-08-07 Thread Ondrej Zary
 psmouse serio_raw sg 
8139cp wmi hwmon ttm parport_pc parport intel_agp
[  122.093295] CPU: 0 PID: 1821 Comm: scsi_eh_2 Tainted: GW 
4.17.0+ #263
[  122.093295] Hardware name:  /i440ZX-W977TF, BIOS 4.51 PG 07/12/00
[  122.093295] EIP: dma_free_attrs.constprop.8+0x29/0x76 [aha1542]
[  122.093295] EFLAGS: 00010086 CPU: 0
[  122.093295] EAX: cfbda200 EBX: 0086 ECX:  EDX: 0006
[  122.093295] ESI: c009 EDI: cf514aa0 EBP: cbe89ebc ESP: cbe89eac
[  122.093295]  DS: 007b ES: 007b FS: 00d8 GS:  SS: 0068
[  122.093295] CR0: 80050033 CR2: 08321408 CR3: 0bcee000 CR4: 0290
[  122.093295] Call Trace:
[  122.093295]  aha1542_free_cmd+0x29/0x40 [aha1542]
[  122.093295]  aha1542_reset+0xb0/0xe5 [aha1542]
[  122.093295]  aha1542_host_reset+0xd/0xf [aha1542]
[  122.093295]  scsi_try_host_reset+0x4c/0x95
[  122.093295]  scsi_eh_ready_devs+0x689/0x781
[  122.093295]  scsi_error_handler+0x268/0x4b0
[  122.093295]  ? __schedule+0x38f/0x3dd
[  122.093295]  kthread+0xcc/0xce
[  122.093295]  ? scsi_eh_get_sense+0x16e/0x16e
[  122.093295]  ? kthread_cancel_delayed_work_sync+0xf/0xf
[  122.093295]  ret_from_fork+0x2e/0x38
[  122.093295] Code: 5d c3 55 85 c0 89 e5 57 56 53 53 74 0a 8b b8 20 01 00 00 
85 ff 75 0c 8b 3d 08 aa 66 cf 85 ff 75 02 0f 0b 9c 5b 0f ba e3 09 72 02 <0f> 0b 
89 45 f0 8d 42 ff 89 cb c1 e8 0c 83 c9 ff 89 d6 0f bd d0 
[  122.093295] ---[ end trace 3524d2ff63a5e03d ]---
[  122.093295] WARNING: CPU: 0 PID: 1821 at ./include/linux/dma-mapping.h:541 
dma_free_attrs.constprop.8+0x29/0x76 [aha1542]
[  122.093295] Modules linked in: aha1542 i2c_dev nouveau psmouse serio_raw sg 
8139cp wmi hwmon ttm parport_pc parport intel_agp
[  122.093295] CPU: 0 PID: 1821 Comm: scsi_eh_2 Tainted: GW 
4.17.0+ #263
[  122.093295] Hardware name:  /i440ZX-W977TF, BIOS 4.51 PG 07/12/00
[  122.093295] EIP: dma_free_attrs.constprop.8+0x29/0x76 [aha1542]
[  122.093295] EFLAGS: 00010086 CPU: 0
[  122.093295] EAX: cfbda200 EBX: 0086 ECX:  EDX: 0006
[  122.093295] ESI: c009 EDI: cf514aa0 EBP: cbe89ebc ESP: cbe89eac
[  122.093295]  DS: 007b ES: 007b FS: 00d8 GS:  SS: 0068
[  122.093295] CR0: 80050033 CR2: 08321408 CR3: 0bcee000 CR4: 0290
[  122.093295] Call Trace:
[  122.093295]  aha1542_free_cmd+0x29/0x40 [aha1542]
[  122.093295]  aha1542_reset+0xb0/0xe5 [aha1542]
[  122.093295]  aha1542_host_reset+0xd/0xf [aha1542]
[  122.093295]  scsi_try_host_reset+0x4c/0x95
[  122.093295]  scsi_eh_ready_devs+0x689/0x781
[  122.093295]  scsi_error_handler+0x268/0x4b0
[  122.093295]  ? __schedule+0x38f/0x3dd
[  122.093295]  kthread+0xcc/0xce
[  122.093295]  ? scsi_eh_get_sense+0x16e/0x16e
[  122.093295]  ? kthread_cancel_delayed_work_sync+0xf/0xf
[  122.093295]  ret_from_fork+0x2e/0x38
[  122.093295] Code: 5d c3 55 85 c0 89 e5 57 56 53 53 74 0a 8b b8 20 01 00 00 
85 ff 75 0c 8b 3d 08 aa 66 cf 85 ff 75 02 0f 0b 9c 5b 0f ba e3 09 72 02 <0f> 0b 
89 45 f0 8d 42 ff 89 cb c1 e8 0c 83 c9 ff 89 d6 0f bd d0 
[  122.093295] ---[ end trace 3524d2ff63a5e03e ]---
[  132.580275] scsi 2:0:1:0: tag#0 Trying device reset for target
[  132.585659] scsi 2:0:1:0: Device offlined - not ready after error recovery
[  132.830010] scsi host2: Unexpected interrupt
[  132.833680] scsi host2: tarstat=0, hastat=0 idlun=20 ccb#=0
[  133.083186] scsi host2: Unexpected interrupt
[  133.087100] scsi host2: tarstat=0, hastat=0 idlun=20 ccb#=0


-- 
Ondrej Zary


Re: [PATCH] aha1542: convert to DMA mapping API

2018-08-06 Thread Ondrej Zary
> +   aha1542->ccb, aha1542->ccb_handle);
> + dma_free_coherent(dev, AHA1542_MAILBOXES * 2 * sizeof(struct mailbox),
> +   aha1542->mb, aha1542->mb_handle);
>   if (sh->dma_channel != 0xff)
>   free_dma(sh->dma_channel);
>   if (sh->irq)
> @@ -826,7 +868,8 @@ static int aha1542_dev_reset(struct scsi_cmnd *cmd)
>
>   aha1542->aha1542_last_mbo_used = mbo;
>
> - any2scsi(mb[mbo].ccbptr, isa_virt_to_bus(&ccb[mbo]));   /* This gets
> trashed for some reason */ +  /* This gets trashed for some reason */
> + any2scsi(mb[mbo].ccbptr, aha1542->ccb_handle + mbo * sizeof(ccb));
>
>   memset(&ccb[mbo], 0, sizeof(struct ccb));
>
> @@ -889,8 +932,7 @@ static int aha1542_reset(struct scsi_cmnd *cmd, u8
> reset_cmd)
>
>   for (i = 0; i < AHA1542_MAILBOXES; i++) {
>   if (aha1542->int_cmds[i] != NULL) {
> - struct scsi_cmnd *tmp_cmd;
> - tmp_cmd = aha1542->int_cmds[i];
> + struct scsi_cmnd *tmp_cmd = aha1542->int_cmds[i];
>
>   if (tmp_cmd->device->soft_reset) {
>   /*
> @@ -901,8 +943,7 @@ static int aha1542_reset(struct scsi_cmnd *cmd, u8
> reset_cmd) */
>   continue;
>   }
> - kfree(tmp_cmd->host_scribble);
> - tmp_cmd->host_scribble = NULL;
> + aha1542_free_cmd(tmp_cmd);
>   aha1542->int_cmds[i] = NULL;
>   aha1542->mb[i].status = 0;
>   }
> @@ -946,6 +987,7 @@ static struct scsi_host_template driver_template = {
>   .module = THIS_MODULE,
>   .proc_name  = "aha1542",
>   .name   = "Adaptec 1542",
> + .cmd_size   = sizeof(struct aha1542_cmd),
>   .queuecommand   = aha1542_queuecommand,
>   .eh_device_reset_handler= aha1542_dev_reset,
>   .eh_bus_reset_handler   = aha1542_bus_reset,

Doesn't seem to work:
[  159.185536] scsi host2: Adaptec AHA-1542 (SCSI-ID 7) at IO 0x330, IRQ 11, 
DMA 7
[  159.262108] BUG: unable to handle kernel NULL pointer dereference at 
[  159.264103] *pde = 
[  159.264103] Oops: 0002 [#1] SMP
[  159.264103] Modules linked in: aha1542(+) sr_mod cdrom i2c_dev psmouse 
serio_raw 8139cp nouveau sg parport_pc parport wmi hwmon ttm 
intel_agp [last unloaded: aha1542]
[  159.264103] CPU: 0 PID: 1848 Comm: modprobe Not tainted 4.17.0+ #263
[  159.264103] Hardware name:  /i440ZX-W977TF, BIOS 4.51 PG 07/12/00
[  159.264103] EIP: setup_mailboxes+0x1a/0xb5 [aha1542]
[  159.264103] EFLAGS: 00010246 CPU: 0
[  159.264103] EAX:  EBX: c009 ECX: cfde2164 EDX: 
[  159.264103] ESI: c009 EDI: cbf07d25 EBP: cbf07d08 ESP: cbf07cf8
[  159.264103]  DS: 007b ES: 007b FS: 00d8 GS: 0033 SS: 0068
[  159.264103] CR0: 80050033 CR2: b7e9f050 CR3: 0bc7 CR4: 0290
[  159.264103] Call Trace:
[  159.264103]  aha1542_hw_init.constprop.7+0x5a8/0x702 [aha1542]
[  159.264103]  aha1542_isa_match+0xb/0x1e [aha1542]
[  159.264103]  isa_bus_match+0x20/0x40
[  159.264103]  __device_attach_driver+0x25/0x71
[  159.264103]  bus_for_each_drv+0x5c/0x68
[  159.264103]  __device_attach+0x79/0xcd
[  159.264103]  ? driver_allows_async_probing+0x28/0x28
[  159.264103]  device_initial_probe+0xd/0xf
[  159.264103]  bus_probe_device+0x22/0x65
[  159.264103]  device_add+0x368/0x434
[  159.264103]  ? pm_runtime_init+0xa5/0xac
[  159.264103]  device_register+0x12/0x15
[  159.264103]  isa_register_driver+0xad/0x10a
[  159.264103]  ? 0xd0d24000
[  159.264103]  aha1542_init+0x33/0x1000 [aha1542]
[  159.264103]  do_one_initcall+0x60/0x11f
[  159.264103]  ? _cond_resched+0x1e/0x22
[  159.264103]  ? slab_pre_alloc_hook+0x25/0x35
[  159.264103]  ? do_init_module+0x17/0x1ad
[  159.264103]  ? kmem_cache_alloc+0x79/0x9c
[  159.264103]  ? do_init_module+0x17/0x1ad
[  159.264103]  do_init_module+0x46/0x1ad
[  159.264103]  load_module+0x1708/0x1b23
[  159.264103]  ? kernel_read_file+0x116/0x143
[  159.264103]  sys_finit_module+0x62/0x67
[  159.264103]  do_int80_syscall_32+0x50/0x62
[  159.264103]  entry_INT80_32+0x2a/0x2a
[  159.264103] EIP: 0xb7f66a02
[  159.264103] EFLAGS: 0292 CPU: 0
[  159.264103] EAX: ffda EBX: 0003 ECX: 004fa970 EDX: 
[  159.264103] ESI: 00563e30 EDI: 00563ef8 EBP:  ESP: bf9100d8
[  159.264103]  DS: 007b ES: 007b FS:  GS: 0033 SS: 007b
[  159.264103] Code: 40 54 e8 44 ff ff ff c7 43 54 00 00 00 00 5b 5d c3 55 89 
e5 56 53 89 c3 83 ec 08 31 c0 c6 45 f3 01 c6 45 f4 08 8b 93 7c 
04 00 00  04 02 00 6b d0 0b 8b b3 7c 04 00 00 03 93 88 04 00 00 01 c6
[  159.264103] EIP: setup_mailboxes+0x1a/0xb5 [aha1542] SS:ESP: 0068:cbf07cf8
[  159.264103] CR2: 
[  159.479491] ---[ end trace 139123655cd08eca ]---



-- 
Ondrej Zary


Re: [PATCH v7 0/6] g_NCR5380: PDMA fixes and cleanup

2017-07-04 Thread Ondrej Zary
On Monday 03 July 2017 09:59:05 Finn Thain wrote:
> Ondrej, would you please test this new series?
>
> Changed since v1:
> - PDMA transfer residual is calculated earlier.
> - End of DMA flag check is now polled (if there is any residual).
>
> Changed since v2:
> - Bail out of transfer loops when Gated IRQ gets asserted.
> - Make udelay conditional on board type.
> - Drop sg_tablesize patch due to performance regression.
>
> Changed since v3:
> - Add Ondrej's workaround for corrupt WRITE commands on DTC boards.
> - Reset the 53c400 logic after any short PDMA transfer.
> - Don't fail the transfer if the 53c400 logic got a reset.
>
> Changed since v4:
> - Bail out of transfer loops when Gated IRQ gets asserted. (Again.)
> - Always call wait_for_53c80_registers() at end of transfer.
> - Drain chip buffers after PDMA receive is interrupted.
> - Rework residual calculation.
> - Add new patch to correct DMA terminology.
>
> Changed since v5:
> - Rework residual calculation to account for on-chip buffer swap.
> - Attempt to retain the disconnect/IRQ detection in the DTC436 workaround.
> - Move all DTC436 workarounds to final patch.
>
> Changed since v6:
> - Fix residual calculation for the buffer timeout case.
> - Iterate after sending final 128 bytes to check for buffer timeout.
> - Don't log the residual value when it is known to be zero.
>
>
> Finn Thain (2):
>   g_NCR5380: Cleanup comments and whitespace
>   g_NCR5380: Use unambiguous terminology for PDMA send and receive
>
> Ondrej Zary (4):
>   g_NCR5380: Fix PDMA transfer size
>   g_NCR5380: End PDMA transfer correctly on target disconnection
>   g_NCR5380: Re-work PDMA loops
>   g_NCR5380: Two DTC436 PDMA workarounds
>
>  drivers/scsi/g_NCR5380.c | 277
> ++- 1 file changed, 155
> insertions(+), 122 deletions(-)

Everything works fine! No corruption, no hangs, rescan-scsi-bus works.

Tested cards:
Canon FG2-5202 (53C400 chip, MMIO)
DTC-3181L (DTCT-436P chip, PIO)
HP C2502 (53C400A chip, PIO)

Tested devices:
QUANTUM  LP240S GM240S01X 4.6
IBM  DORS-32160   WA0A
SONY CD-ROM CDU-415   1.1g
SONY CD-ROM CDU-55S   1.0t

Tested-by: Ondrej Zary 

-- 
Ondrej Zary


Re: [PATCH v6 0/6] g_NCR5380: PDMA fixes and cleanup

2017-07-02 Thread Ondrej Zary
On Sunday 02 July 2017 05:11:27 Finn Thain wrote:
> On Sat, 1 Jul 2017, Ondrej Zary wrote:
> > The write corruption is still present - "start" must be rolled back in
> > both IRQ and timeout cases.
>
> Your original algorithm aborts the transfer for a timeout. Same with mine.

I do "start -= 2 * 128" even after timeout.

> The bug must be a elsewhere.
>
> > And 128 B is not enough , 256 is OK (why did it work last time?).
>
> When I get contradictory results it usually means I booted the wrong build
> or built the wrong branch.

I've just retested PATCHv5, it really misses 128 bytes and works if I
add "residual += 128;".

> Actually, I think that adding 128 to the residual is correct in some
> sitations, and 256 is correct in other situations.
>
> > We just wrote a buffer to the chip but the chip is writing the previous
> > one to the drive - so if a problem arises, both buffers are lost.
>
> I see. I guess we have to take buffer swaps into account.
>
> > This fixes the corruption (although the "start > 0" check seems wrong
> > now): --- a/drivers/scsi/g_NCR5380.c
> > +++ b/drivers/scsi/g_NCR5380.c
> > @@ -598,23 +598,17 @@ static inline int generic_NCR5380_psend(struct
> > NCR5380_hostdata *hostdata, CSR_HOST_BUF_NOT_RDY, 0,
> >hostdata->c400_ctl_status,
> >CSR_GATED_53C80_IRQ,
> > -  CSR_GATED_53C80_IRQ, HZ / 64) < 0)
> > -   break;
> > -
> > -   if (NCR5380_read(hostdata->c400_ctl_status) &
> > -   CSR_HOST_BUF_NOT_RDY) {
> > +  CSR_GATED_53C80_IRQ, HZ / 64) < 0 ||
> > +   (NCR5380_read(hostdata->c400_ctl_status) &
> > +(CSR_HOST_BUF_NOT_RDY | CSR_GATED_53C80_IRQ))) {
>
> You could add a printk to the timeout branch. If it executes, something is
> seriously wrong. E.g.
>
> - break;
> + { pr_err("send timeout %02x, %d/%d\n",
> NCR5380_read(hostdata->c400_ctl_status), start, len); break; }

Yes, timeouts do happen:
[ 9671.909223] send timeout 14, 3840/4096
[ 9672.978079] send timeout 14, 2816/4096
[ 9675.323751] send timeout 14, 1280/4096

> > /* The chip has done a 128 B buffer swap but the first
> >  * buffer still has not reached the SCSI bus.
> >  */
> > if (start > 0)
> > -   start -= 128;
> > +   start -= 256;
> > break;
> > }
>
> BTW, that change carries the risk of 'start' going negative and the
> residual exceeding the length of the original transfer.
>
> But I agree with you that there's a problem with the residual.
>
> If I understand correctly, the 53c400 can't do a buffer swap until the
> disk acknowledges each of the 128 bytes from the buffer. But I guess the
> first buffer is special because the disk will not see the first byte of
> the transfer until after the first buffer swap.
>
> And it appears that the last buffer is also special: we have to wait for
> CSR_HOST_BUF_NOT_RDY even after start == len otherwise we may not detect a
> failure and fix the residual. So I think the datasheet is right; we have
> to iterate until the block counter goes to zero.
>
> I think it is safe to say that when CSR_HOST_BUF_NOT_RDY, 'start' is
> between 128 and 256 B ahead of the disk. Otherwise, the host buffer is
> empty and 'start' is no more than 128 B ahead of the disk.
>
> > -   if (NCR5380_read(hostdata->c400_ctl_status) &
> > -   CSR_GATED_53C80_IRQ)
> > -   break;
> > -
> > if (hostdata->io_port && hostdata->io_width == 2)
> > outsw(hostdata->io_port + hostdata->c400_host_buf,
> >   src + start, 64);
> >
> >
> > DTC seems to work too.
>
> OK. Thanks for testing. Please try the patch below on top of v6.

It misses 256B blocks. It's caused by the timeouts, this patch fixes it:

--- a/drivers/scsi/g_NCR5380.c
+++ b/drivers/scsi/g_NCR5380.c
@@ -598,11 +598,9 @@ static inline int generic_NCR5380_psend(struct 
NCR5380_hostdata *hostdata,
   CSR_HOST_BUF_NOT_RDY, 0,
   hostdata->c400_ctl_status,
   CSR_GATED_53C80_IRQ,
-  CSR_GATED_53C80_IRQ, HZ / 64) < 0)
-   break;
-
-   if (NCR5380_read(hostdata->c400_ctl_status) &
-   CSR_HOST_BUF_NOT_RDY) {
+  CSR_GATED_53C80_IRQ, HZ / 64) < 0 ||
+   (NCR5380_read(hostdata->c400_ctl_status) &
+CSR_HOST_BUF_NOT_RDY)) {
/* Both 128 B buffers are in use */
if (start >= 128)
start -= 128;


-- 
Ondrej Zary


Re: [PATCH v6 0/6] g_NCR5380: PDMA fixes and cleanup

2017-07-01 Thread Ondrej Zary
On Saturday 01 July 2017 04:40:53 Finn Thain wrote:
> Ondrej, would you please test this new series?
>
> Changed since v1:
> - PDMA transfer residual is calculated earlier.
> - End of DMA flag check is now polled (if there is any residual).
>
> Changed since v2:
> - Bail out of transfer loops when Gated IRQ gets asserted.
> - Make udelay conditional on board type.
> - Drop sg_tablesize patch due to performance regression.
>
> Changed since v3:
> - Add Ondrej's workaround for corrupt WRITE commands on DTC boards.
> - Reset the 53c400 logic after any short PDMA transfer.
> - Don't fail the transfer if the 53c400 logic got a reset.
>
> Changed since v4:
> - Bail out of transfer loops when Gated IRQ gets asserted. (Again.)
> - Always call wait_for_53c80_registers() at end of transfer.
> - Drain chip buffers after PDMA receive is interrupted.
> - Rework residual calculation.
> - Add new patch to correct DMA terminology.
>
> Changed since v5:
> - Rework residual calculation to account for on-chip buffer swap.
> - Attempt to retain the disconnect/IRQ detection in the DTC436 workaround.
> - Move all DTC436 workarounds to final patch.
>
>
> Finn Thain (2):
>   g_NCR5380: Cleanup comments and whitespace
>   g_NCR5380: Use unambiguous terminology for PDMA send and receive
>
> Ondrej Zary (4):
>   g_NCR5380: Fix PDMA transfer size
>   g_NCR5380: End PDMA transfer correctly on target disconnection
>   g_NCR5380: Re-work PDMA loops
>   g_NCR5380: Various DTC436 workarounds
>
>  drivers/scsi/g_NCR5380.c | 273
> ++- 1 file changed, 151
> insertions(+), 122 deletions(-)

The write corruption is still present - "start" must be rolled back in both
IRQ and timeout cases. And 128 B is not enough , 256 is OK (why did it work
last time?). We just wrote a buffer to the chip but the chip is writing the
previous one to the drive - so if a problem arises, both buffers are lost.

This fixes the corruption (although the "start > 0" check seems wrong now):
--- a/drivers/scsi/g_NCR5380.c
+++ b/drivers/scsi/g_NCR5380.c
@@ -598,23 +598,17 @@ static inline int generic_NCR5380_psend(struct 
NCR5380_hostdata *hostdata,
   CSR_HOST_BUF_NOT_RDY, 0,
   hostdata->c400_ctl_status,
   CSR_GATED_53C80_IRQ,
-  CSR_GATED_53C80_IRQ, HZ / 64) < 0)
-   break;
-
-   if (NCR5380_read(hostdata->c400_ctl_status) &
-   CSR_HOST_BUF_NOT_RDY) {
+  CSR_GATED_53C80_IRQ, HZ / 64) < 0 ||
+   (NCR5380_read(hostdata->c400_ctl_status) &
+(CSR_HOST_BUF_NOT_RDY | CSR_GATED_53C80_IRQ))) {
/* The chip has done a 128 B buffer swap but the first
 * buffer still has not reached the SCSI bus.
 */
if (start > 0)
-   start -= 128;
+   start -= 256;
break;
}
 
-   if (NCR5380_read(hostdata->c400_ctl_status) &
-   CSR_GATED_53C80_IRQ)
-   break;
-
if (hostdata->io_port && hostdata->io_width == 2)
outsw(hostdata->io_port + hostdata->c400_host_buf,
  src + start, 64);


DTC seems to work too.

-- 
Ondrej Zary


Re: [PATCH v5 0/6] g_NCR5380: PDMA fixes and cleanup

2017-06-30 Thread Ondrej Zary
On Friday 30 June 2017 09:12:37 Finn Thain wrote:
> On Thu, 29 Jun 2017, Ondrej Zary wrote:
> > The write corruption is still there. I'm afraid it can't be fixed
> > without rolling "start" back (or inceasing residual) if an error
> > occured, something like this:
> >
> > --- a/drivers/scsi/g_NCR5380.c
> > +++ b/drivers/scsi/g_NCR5380.c
> > @@ -619,6 +621,9 @@ static inline int generic_NCR5380_psend(struct
> >(int)NCR5380_read(hostdata->c400_blk_cnt) * 128);
> >
> > if (residual != 0) {
> > +   residual += 128;
> > /* 53c80 interrupt or transfer timeout. Reset 53c400 logic. */
> > NCR5380_write(hostdata->c400_ctl_status, CSR_RESET);
> > NCR5380_write(hostdata->c400_ctl_status, CSR_BASE);
> >
> > (seems to work - wrote 230MB and read it back with no differences)
> >
> > The corruption mechanism is:
> > 1. Host buffer is ready so we write 128 B of data there and increment
> >"start".
> > 2. Chip swaps the buffers, decrements the block counter and starts
> >writing the data to drive.
> > 3. Drive does not like it (e.g. its buffer is full) so it disconnects.
> > 4. Chip stops writing and asserts an IRQ.
> > 5. We detect the IRQ. The block counter is already decremented, "start"
> >is already incremented but the data was not written to the drive.
>
> OK. Thanks for that analysis.
>
> It sounds like the c400_blk_cnt value gives the number of buffer swaps
> remaining. If so, that value isn't useful for calculating a residual. I'll
> rework that calculation again.
>
> In your patch, the residual gets increased regardless of the actual cause
> of the short transfer. Nothing prevents the residual from being increased
> beyond the original length of the transfer (due to a flaky target or bus).
> Therefore I've taken a slightly different approach in my patch (below).

Yes, that's wrong. My original patch had "start -= 128" and then check for 
negative value.

> > No more log spamming on DTC but reads are corrupted even more than
> > before. The IRQ check after data transfer increases the chance of
> > catching an IRQ before the buffer could become ready.
>
> If we delay the IRQ check, that just means that CSR_GATED_53C80_IRQ will
> be detected a bit later (128 bytes later)... so not much difference.

The main difference is that my original patch read the CSR once and then:
- transfer data if the buffer is ready, ignoring any IRQ
- if the buffer is not ready, check for an IRQ
- if neither buffer is ready nor IRQ was asserted, check for timeout

So yes, the IRQ will be detected 128 bytes later - but the IRQ is asserted at 
3968 bytes which means the transfer will then be complete.

> > This patch:
> > --- a/drivers/scsi/g_NCR5380.c
> > +++ b/drivers/scsi/g_NCR5380.c
> > @@ -548,8 +548,10 @@ static inline int generic_NCR5380_precv(struct
> > start += 128;
> >
> > if (NCR5380_read(hostdata->c400_ctl_status) &
> > -   CSR_GATED_53C80_IRQ)
> > +   CSR_GATED_53C80_IRQ) {
> > +   printk("r irq at start=%d basr=0x%02x\n", start,
> > NCR5380_read(BUS_AND_STATUS_REG)); break;
> > +   }
> > }
> >
> > residual = len - start;
> >
> > produces lots of these lines:
> > [  896.194054] r irq at start=128 basr=0x98
> > [  896.197758] r irq at start=3968 basr=0x98
>
> Assuming that the registers are available and valid, the value 0x98 means
> BASR_END_DMA_TRANSFER | BASR_IRQ | BASR_PHASE_MATCH. There is no
> BASR_BUSY_ERROR here, so the cause of the CSR_GATED_53C80_IRQ must be that
> the 53c400 has terminated the transfer by asserting /EOP. That shouldn't
> happen before before the counters run down.
>
> It doesn't make sense. So maybe the 53c80 registers are not valid at this
> point? That means a phase mismatch can't be excluded... unlikely at 128
> bytes into the transfer. Busy error? Also unlikely.
>
> I have to conclude that CSR_GATED_53C80_IRQ and BASR_END_DMA_TRANSFER
> can't be trusted on this board. I guess that's why you examine the BASR
> directly in your original algorithm but ignore BASR_END_DMA_TRANSFER.

Exactly, BASR_END_DMA_TRANSFER causes problems on DTC.

> It does look like some kind of timing issue: the "start" value above
> changes from one log message to the next. Who knows?

Only that two values (128 and 3968) appeared. 3968 = 4096-128, one block 
before the end of transfer. So probably BASR_END_DMA_TRANSFER is asserted one 
block earlier (i.e. 

Re: [PATCH v5 0/6] g_NCR5380: PDMA fixes and cleanup

2017-06-29 Thread Ondrej Zary
On Thursday 29 June 2017 07:24:18 Finn Thain wrote:
> Ondrej, would you please test this new series?
>
> Changed since v1:
> - PDMA transfer residual is calculated earlier.
> - End of DMA flag check is now polled (if there is any residual).
>
> Changed since v2:
> - Bail out of transfer loops when Gated IRQ gets asserted.
> - Make udelay conditional on board type.
> - Drop sg_tablesize patch due to performance regression.
>
> Changed since v3:
> - Add Ondrej's workaround for corrupt WRITE commands on DTC boards.
> - Reset the 53c400 logic after any short PDMA transfer.
> - Don't fail the transfer if the 53c400 logic got a reset.
>
> Changed since v4:
> - Bail out of transfer loops when Gated IRQ gets asserted. (Again.)
> - Always call wait_for_53c80_registers() at end of transfer.
> - Drain chip buffers after PDMA receive is interrupted.
> - Rework residual calculation.
> - Add new patch to correct DMA terminology.
>
>
> Finn Thain (2):
>   g_NCR5380: Cleanup comments and whitespace
>   g_NCR5380: Use unambiguous terminology for PDMA send and receive
>
> Ondrej Zary (4):
>   g_NCR5380: Fix PDMA transfer size
>   g_NCR5380: End PDMA transfer correctly on target disconnection
>   g_NCR5380: Limit PDMA send to 512 B to avoid data corruption on
> DTC3181E
>   g_NCR5380: Re-work PDMA loops
>
>  drivers/scsi/g_NCR5380.c | 260
> +-- 1 file changed, 139
> insertions(+), 121 deletions(-)

This fixes the DTC read corruption, although I don't like the repeated
ctl_status register reads:
--- a/drivers/scsi/g_NCR5380.c
+++ b/drivers/scsi/g_NCR5380.c
@@ -533,7 +533,7 @@ static inline int generic_NCR5380_precv(struct 
NCR5380_hostdata *hostdata,
break;

if (NCR5380_read(hostdata->c400_ctl_status) &
-   CSR_HOST_BUF_NOT_RDY)
+   CSR_GATED_53C80_IRQ && 
(NCR5380_read(hostdata->c400_ctl_status) & CSR_HOST_BUF_NOT_RDY))
break;

if (hostdata->io_port && hostdata->io_width == 2)
@@ -546,10 +546,6 @@ static inline int generic_NCR5380_precv(struct 
NCR5380_hostdata *hostdata,
memcpy_fromio(dst + start,
hostdata->io + NCR53C400_host_buffer, 128);
start += 128;
-
-   if (NCR5380_read(hostdata->c400_ctl_status) &
-   CSR_GATED_53C80_IRQ)
-   break;
}
 
residual = len - start;

Writes seem to work correctly.

-- 
Ondrej Zary


Re: [PATCH v5 0/6] g_NCR5380: PDMA fixes and cleanup

2017-06-29 Thread Ondrej Zary
On Thursday 29 June 2017 07:24:18 Finn Thain wrote:
> Ondrej, would you please test this new series?
>
> Changed since v1:
> - PDMA transfer residual is calculated earlier.
> - End of DMA flag check is now polled (if there is any residual).
>
> Changed since v2:
> - Bail out of transfer loops when Gated IRQ gets asserted.
> - Make udelay conditional on board type.
> - Drop sg_tablesize patch due to performance regression.
>
> Changed since v3:
> - Add Ondrej's workaround for corrupt WRITE commands on DTC boards.
> - Reset the 53c400 logic after any short PDMA transfer.
> - Don't fail the transfer if the 53c400 logic got a reset.
>
> Changed since v4:
> - Bail out of transfer loops when Gated IRQ gets asserted. (Again.)
> - Always call wait_for_53c80_registers() at end of transfer.
> - Drain chip buffers after PDMA receive is interrupted.
> - Rework residual calculation.
> - Add new patch to correct DMA terminology.
>
>
> Finn Thain (2):
>   g_NCR5380: Cleanup comments and whitespace
>   g_NCR5380: Use unambiguous terminology for PDMA send and receive
>
> Ondrej Zary (4):
>   g_NCR5380: Fix PDMA transfer size
>   g_NCR5380: End PDMA transfer correctly on target disconnection
>   g_NCR5380: Limit PDMA send to 512 B to avoid data corruption on
> DTC3181E
>   g_NCR5380: Re-work PDMA loops
>
>  drivers/scsi/g_NCR5380.c | 260
> +-- 1 file changed, 139
> insertions(+), 121 deletions(-)

The write corruption is still there. I'm afraid it can't be fixed without
rolling "start" back (or inceasing residual) if an error occured, something 
like this:
--- a/drivers/scsi/g_NCR5380.c
+++ b/drivers/scsi/g_NCR5380.c
@@ -619,6 +621,9 @@ static inline int generic_NCR5380_psend(struct 
NCR5380_hostdata *hostdata,
   (int)NCR5380_read(hostdata->c400_blk_cnt) * 128);

if (residual != 0) {
+   residual += 128;
/* 53c80 interrupt or transfer timeout. Reset 53c400 logic. */
NCR5380_write(hostdata->c400_ctl_status, CSR_RESET);
NCR5380_write(hostdata->c400_ctl_status, CSR_BASE);

(seems to work - wrote 230MB and read it back with no differences)

The corruption mechanism is:
1. Host buffer is ready so we write 128 B of data there and increment "start".
2. Chip swaps the buffers, decrements the block counter and starts writing the
data to drive.
3. Drive does not like it (e.g. its buffer is full) so it disconnects.
4. Chip stops writing and asserts an IRQ.
5. We detect the IRQ. The block counter is already decremented, "start" is
already incremented but the data was not written to the drive.



No more log spamming on DTC but reads are corrupted even more than before.
The IRQ check after data transfer increases the chance of catching an IRQ
before the buffer could become ready. This patch:
--- a/drivers/scsi/g_NCR5380.c
+++ b/drivers/scsi/g_NCR5380.c
@@ -548,8 +548,10 @@ static inline int generic_NCR5380_precv(struct 
NCR5380_hostdata *hostdata,
start += 128;
 
if (NCR5380_read(hostdata->c400_ctl_status) &
-   CSR_GATED_53C80_IRQ)
+   CSR_GATED_53C80_IRQ) {
+   printk("r irq at start=%d basr=0x%02x\n", start, 
NCR5380_read(BUS_AND_STATUS_REG));
break;
+       }
}
 
residual = len - start;

produces lots of these lines:
[  896.194054] r irq at start=128 basr=0x98
[  896.197758] r irq at start=3968 basr=0x98


-- 
Ondrej Zary


Re: [PATCH v4 0/5] g_NCR5380: PDMA fixes and cleanup

2017-06-28 Thread Ondrej Zary
On Wednesday 28 June 2017 06:04:36 Finn Thain wrote:
> Ondrej, would you please test this new series?
>
> Changed since v1:
> - PDMA transfer residual is calculated earlier.
> - End of DMA flag check is now polled (if there is any residual).
>
> Changed since v2:
> - Bail out of transfer loops when Gated IRQ gets asserted.
> - Make udelay conditional on board type.
> - Drop sg_tablesize patch due to performance regression.
>
> Changed since v3:
> - Add Ondrej's workaround for corrupt WRITE commands on DTC boards.
> - Reset the 53c400 logic after any short PDMA transfer.
> - Don't fail the transfer if the 53c400 logic got a reset.
>
>
> Finn Thain (1):
>   g_NCR5380: Cleanup comments and whitespace
>
> Ondrej Zary (4):
>   g_NCR5380: Fix PDMA transfer size
>   g_NCR5380: End PDMA transfer correctly on target disconnection
>   g_NCR5380: Limit PDMA send to 512 B to avoid random corruption on
> DTC3181E
>   g_NCR5380: Re-work PDMA loops
>
>  drivers/scsi/g_NCR5380.c | 239
> --- 1 file changed, 120
> insertions(+), 119 deletions(-)

Now read seems to work on non-DTC chips.
Writes continue in PDMA after disconnect but there's a corruption - one 128 B 
block missing on disconnect.


On DTC, the log is spammed with errors like this:
sd 2:0:1:0: [sdb] tag#0 generic_NCR5380_pread: End of DMA timeout (0)

They're cause by read corruption on DTC:
pread() is breaking at start=3968 because of an end-of-DMA IRQ (BASR=0x98) but 
pdma_residual is set to zero (block counter is zero because the data was read 
into the buffer but we did not read it from there). So we lose one buffer of 
data on each 4 KB read.
The PDMA is then reset which probably means BASR_END_DMA_TRANSFER will not be 
asserted.


-- 
Ondrej Zary


Re: [PATCH v3 0/4] g_NCR5380: PDMA fixes and cleanup

2017-06-27 Thread Ondrej Zary
On Tuesday 27 June 2017 03:49:16 Finn Thain wrote:
> On Mon, 26 Jun 2017, Ondrej Zary wrote:
> > No apparent change in behavior, the first write test resulted in:
> > [  842.830802] sd 2:0:1:0: [sdb] tag#0 53c80 registers not accessible,
> > device will be reset [  842.830802] sd 2:0:1:0: [sdb] tag#0 switching to
> > slow handshake
> >
> > Checking for IRQ after poll_politely2 does not seem right because we can
> > miss the buffer ready signal.
>
> How so? As long as there's no gated IRQ, we poll for buffer readiness
> until timeout. And when there is a gated IRQ, we break both the polling
> loop and the transfer loop immediately. Your code and mine are basically
> in agreement here.

Yes, it stops transfer when an IRQ arrives. But the host buffer could be ready
at the same time. The IRQ can be an "end-of-DMA" IRQ (IIRC DTC chips assert
this earlier than 53C400). Or just a disconnect that occured right now but the
chip already read a buffer full of data.

> > According to my tests, buffer ready signal is most important - if there
> > is any data to read/write, do the transfer. If not, only then check why
> > - maybe we got an IRQ (that terminated PDMA). Or no IRQ, sometimes the
> > wait for buffer ready times out - we need to terminate PDMA manually
> > then (reset).
> >
> > Then 53C80 registers should become ready.
>
> You seem to be saying that we should ignore the IRQ signal if the buffers
> have become ready. Maybe so. Can we try simply resetting the block
> counter? (I could imagine that the 53c400 core might leave the 53c80
> registers inaccessible unless we keep accessing the buffers in the 53c400
> core until the transfer is done.)

We can't reset the block counter because 0 means 256 blocks to transfer (page
13 in datasheet).
Yes, the 53C80 registers seem to become available only when the PDMA transfer
ends by either:
1. transferring all blocks (block counter decrementing to zero)
2. IRQ
3. reset

> BTW, with regard to your patch, note that this construct is race prone:
>
> while (1) {   /* monitor IRQ while waiting for host buffer */
>   csr = NCR5380_read(hostdata->c400_ctl_status);
>   if (!(csr & CSR_HOST_BUF_NOT_RDY))
>   break;
>   if (csr & CSR_GATED_53C80_IRQ) {
>   basr = NCR5380_read(BUS_AND_STATUS_REG);
>   if (!(basr & BASR_PHASE_MATCH) ||
>  (basr & BASR_BUSY_ERROR)) {
>   printk("basr=0x%02x csr=0x%02x at start=%d\n", basr, 
> csr, start);
>   goto out_wait;
>   }
>   }
>   if (retries-- < 1) {
>   shost_printk(KERN_ERR, hostdata->host, "53C400r: host buffer 
> not ready in
> time\n"); NCR5380_write(hostdata->c400_ctl_status, CSR_RESET);
>   NCR5380_write(hostdata->c400_ctl_status, CSR_BASE);
>   goto out_wait;
>   }
> }
>
> This code can "goto out_wait" when !(csr & CSR_HOST_BUF_NOT_RDY). It
> depends on timing. This would seem to be contrary to your stated aim.
>
> Moreover, this code can also "break" when (csr & CSR_GATED_53C80_IRQ).
> That depends on timing too. But this may be an improvement on my code if
> it allows the 53c80 registers to become accessible, by allowing the block
> counter to be decremented.

Yes, it continue the transfer even if the IRQ is asserted - as long as the
buffer is ready. That's intended.

> The uncertainty here was one of the reasons I reworked this code.

My version reads CSR only once per loop but that probably does not help at all
as the HW state could change anytime. The chip's design seems to be very
race-prone.

> > This is a log from writing 230 MB file using my code with some debug
> > prints, on a NCR53C400. No 53C80 timeouts, only disconnects and some
> > host buffer timeouts (maybe the drive sometimes just slows down without
> > disconnecting?)
> >
> > [ 3378.503828] basr=0x10 csr=0xd5 at start=512
> > [ 3461.257973] w basr=0x10 csr=0x95 at start=3840
> > [ 3461.838225] w basr=0x10 csr=0x95 at start=3840
> > [ 3462.683446] w basr=0x10 csr=0x95 at start=3840
> > [ 3463.416911] w basr=0x10 csr=0x95 at start=3840
> > [ 3465.117804] scsi host2: 53C400w: host buffer not ready in time
> > [ 3465.276375] w basr=0x10 csr=0x95 at start=3328
> > [ 3466.457701] w basr=0x10 csr=0x95 at start=1792
> > [ 3467.019643] scsi host2: 53C400w: host buffer not ready in time
> > [ 3467.619058] scsi host2: 53C400w: host buffer not ready in time
> > [ 3467.799619] w basr=0x10 csr=0x95 at start=3840
> > [ 3552.123501] w basr=0x10 csr=0x95 at start=2304
> > [ 3552.77

Re: [PATCH v3 0/4] g_NCR5380: PDMA fixes and cleanup

2017-06-27 Thread Ondrej Zary
On Tuesday 27 June 2017 14:42:29 Finn Thain wrote:
> On Tue, 27 Jun 2017, Ondrej Zary wrote:
> > BTW. I've probably found the DTC write corruption. Added the following
> > check (13 is host buffer index register) -
>
> That register is not mentioned in my 53c400 datasheet.

Yes, it's not there. But we don't have 53C400A and DTC436 datasheets (this 
register works on both).

> > and it triggers sometimes: the value is 1 instead of 0. As we use only
> > 16-bit writes, I don't see how the value could ever be odd. Looks like a
> > bug in the chip. The index register corrupts during the transfer, not
> > after IRQ or timeout. The same check at beginning of pwrite() did not
> > trigger.
>
> Are you reading this register at the right moment? Have you tried waiting
> for it to reach zero, as in,
>
>   if (NCR5380_poll_politely(hostdata, 13, 0xff, 0, HZ / 64) < 0)
>   /* printk, reset etc */;

I have not but will try (expecting that it will not change by itself).

> Even if this is a reliable way to detect a short transfer, it would be
> nice to know the root cause. But I'm being unrealistic: the DTC436 vendor
> never responded to my requests for technical documentation.

According to the data corruption observed, it's not a short transfer. The 
corruption is always the same: one byte missing at the beginning of a 128 B 
block. It happens only with slow Quantum LPS 240 drive, not with faster IBM 
DORS-32160.

> > The index register is not writable so we must(?) reset the PDMA engine
> > to recover. However, this quick attempt to fix does not work, maybe we
> > should reload the block count and continue?
>
> I don't know if it is possible to recover. If the last byte never reached
> the scsi bus, then once you reset the 53c400 core, you need the driver to
> perform a single-byte PIO transfer after the short PDMA transfer. This
> would require that you set the residual appropriately (though in my
> experience that may not be sufficient).
>
> It may be better to simply limit the transfer to 512 bytes instead of
> attempting to recover based on an undocumented (?) register, etc. Seems
> like a bit of a hack.
>
> > --- a/drivers/scsi/g_NCR5380.c
> > +++ b/drivers/scsi/g_NCR5380.c
> > @@ -595,7 +603,13 @@ static inline int generic_NCR5380_pwrite(struct
> > NCR5380_hostdata *hostdata,
> > goto out_wait;
> > }
> > }
> > -
> > +   idx = NCR5380_read(13);
> > +   if (idx != 0) {
> > +   printk("host idx=%d, start=%d\n", idx, start);
> > +   NCR5380_write(hostdata->c400_ctl_status,
> > CSR_RESET); +  
> > NCR5380_write(hostdata->c400_ctl_status, CSR_BASE); +
> >   goto out_wait;
> > +   }
> > if (hostdata->io_port && hostdata->io_width == 2)
> > outsw(hostdata->io_port +
> > hostdata->c400_host_buf, src + start, 64);
>
> I find it hard to reason about this code. For example, out_wait is to be
> removed. Let's get the preceding patches working and signed-off. Please go
> ahead and use a 512 B transfer for DTC436 testing if that will help get
> this patch series over the line.

OK, I agree. Let's fix the problems first and leave this hack for later.

-- 
Ondrej Zary


Re: [PATCH v3 0/4] g_NCR5380: PDMA fixes and cleanup

2017-06-26 Thread Ondrej Zary
On Monday 26 June 2017, Ondrej Zary wrote:
> On Monday 26 June 2017 09:30:33 Finn Thain wrote:
> > Ondrej, would you please test this new series?
> >
> > Changed since v1:
> > - PDMA transfer residual is calculated earlier.
> > - End of DMA flag check is now polled (if there is any residual).
> >
> > Changed since v2:
> > - Bail out of transfer loops when Gated IRQ gets asserted.
> > - Make udelay conditional on board type.
> > - Drop sg_tablesize patch due to performance regression.
> >
> >
> > Finn Thain (1):
> >   g_NCR5380: Cleanup comments and whitespace
> >
> > Ondrej Zary (3):
> >   g_NCR5380: Fix PDMA transfer size
> >   g_NCR5380: End PDMA transfer correctly on target disconnection
> >   g_NCR5380: Re-work PDMA loops
> >
> >  drivers/scsi/g_NCR5380.c | 239
> > +++ 1 file changed, 116
> > insertions(+), 123 deletions(-)

BTW. I've probably found the DTC write corruption.
Added the following check (13 is host buffer index register) - and it triggers 
sometimes: the value is 1 instead of 0. As we use only 16-bit writes, I don't 
see how the value could ever be odd. Looks like a bug in the chip.
The index register corrupts during the transfer, not after IRQ or timeout. The 
same check at beginning of pwrite() did not trigger.

The index register is not writable so we must(?) reset the PDMA engine to 
recover. However, this quick attempt to fix does not work, maybe we should 
reload the block count and continue?

--- a/drivers/scsi/g_NCR5380.c
+++ b/drivers/scsi/g_NCR5380.c
@@ -595,7 +603,13 @@ static inline int generic_NCR5380_pwrite(struct 
NCR5380_hostdata *hostdata,
goto out_wait;
}
}
-
+   idx = NCR5380_read(13);
+   if (idx != 0) {
+   printk("host idx=%d, start=%d\n", idx, start);
+   NCR5380_write(hostdata->c400_ctl_status, CSR_RESET);
+   NCR5380_write(hostdata->c400_ctl_status, CSR_BASE);
+   goto out_wait;
+   }
if (hostdata->io_port && hostdata->io_width == 2)
outsw(hostdata->io_port + hostdata->c400_host_buf,
src + start, 64);


-- 
Ondrej Zary


Re: [PATCH v3 0/4] g_NCR5380: PDMA fixes and cleanup

2017-06-26 Thread Ondrej Zary
On Monday 26 June 2017 09:30:33 Finn Thain wrote:
> Ondrej, would you please test this new series?
>
> Changed since v1:
> - PDMA transfer residual is calculated earlier.
> - End of DMA flag check is now polled (if there is any residual).
>
> Changed since v2:
> - Bail out of transfer loops when Gated IRQ gets asserted.
> - Make udelay conditional on board type.
> - Drop sg_tablesize patch due to performance regression.
>
>
> Finn Thain (1):
>   g_NCR5380: Cleanup comments and whitespace
>
> Ondrej Zary (3):
>   g_NCR5380: Fix PDMA transfer size
>   g_NCR5380: End PDMA transfer correctly on target disconnection
>   g_NCR5380: Re-work PDMA loops
>
>  drivers/scsi/g_NCR5380.c | 239
> +++ 1 file changed, 116
> insertions(+), 123 deletions(-)

No apparent change in behavior, the first write test resulted in:
[  842.830802] sd 2:0:1:0: [sdb] tag#0 53c80 registers not accessible, device 
will be reset
[  842.830802] sd 2:0:1:0: [sdb] tag#0 switching to slow handshake

Checking for IRQ after poll_politely2 does not seem right because we can
miss the buffer ready signal.

According to my tests, buffer ready signal is most important - if there is
any data to read/write, do the transfer. If not, only then check why - maybe
we got an IRQ (that terminated PDMA). Or no IRQ, sometimes the wait for buffer
ready times out - we need to terminate PDMA manually then (reset).

Then 53C80 registers should become ready.

This is a log from writing 230 MB file using my code with some debug
prints, on a NCR53C400. No 53C80 timeouts, only disconnects and some host
buffer timeouts (maybe the drive sometimes just slows down without
disconnecting?)
[ 3378.503828] basr=0x10 csr=0xd5 at start=512
[ 3461.257973] w basr=0x10 csr=0x95 at start=3840
[ 3461.838225] w basr=0x10 csr=0x95 at start=3840
[ 3462.683446] w basr=0x10 csr=0x95 at start=3840
[ 3463.416911] w basr=0x10 csr=0x95 at start=3840
[ 3465.117804] scsi host2: 53C400w: host buffer not ready in time
[ 3465.276375] w basr=0x10 csr=0x95 at start=3328
[ 3466.457701] w basr=0x10 csr=0x95 at start=1792
[ 3467.019643] scsi host2: 53C400w: host buffer not ready in time
[ 3467.619058] scsi host2: 53C400w: host buffer not ready in time
[ 3467.799619] w basr=0x10 csr=0x95 at start=3840
[ 3552.123501] w basr=0x10 csr=0x95 at start=2304
[ 3552.771223] w basr=0x10 csr=0x95 at start=1280
[ 3554.556451] w basr=0x10 csr=0x95 at start=2816
[ 3555.229646] w basr=0x10 csr=0x95 at start=1792
[ 3555.630632] scsi host2: 53C400w: host buffer not ready in time
[ 3555.774560] w basr=0x10 csr=0x95 at start=768
[ 3625.541608] w basr=0x10 csr=0x95 at start=3328
[ 3640.099861] w basr=0x10 csr=0x95 at start=1792
[ 3641.442671] w basr=0x10 csr=0x95 at start=2816
[ 3641.865469] w basr=0x10 csr=0x95 at start=768
[ 3642.939223] w basr=0x10 csr=0x95 at start=1280
[ 3643.356858] w basr=0x10 csr=0x95 at start=3328
[ 3643.701636] w basr=0x10 csr=0x95 at start=3840
[ 3645.153405] w basr=0x10 csr=0x95 at start=2304
[ 3646.135642] w basr=0x10 csr=0x95 at start=1280
[ 3647.007321] w basr=0x10 csr=0x95 at start=2816
[ 3648.065874] w basr=0x10 csr=0x95 at start=3328
[ 3650.071961] w basr=0x10 csr=0x95 at start=1280
[ 3650.827630] w basr=0x10 csr=0x95 at start=1792
[ 3651.827011] w basr=0x10 csr=0x95 at start=2816
[ 3652.559984] w basr=0x10 csr=0x95 at start=2816
[ 3653.203566] w basr=0x10 csr=0x95 at start=3328
[ 3653.594376] w basr=0x10 csr=0x95 at start=1280
[ 3653.903437] w basr=0x10 csr=0x95 at start=3840
[ 3654.305753] w basr=0x10 csr=0x95 at start=1792
[ 3654.676009] w basr=0x10 csr=0x95 at start=2304
[ 3655.367686] w basr=0x10 csr=0x95 at start=2816
[ 3655.733854] w basr=0x10 csr=0x95 at start=768
[ 3656.075023] w basr=0x10 csr=0x95 at start=3328
[ 3656.493046] w basr=0x10 csr=0x95 at start=2816
[ 3657.208089] w basr=0x10 csr=0x95 at start=1280
[ 3657.537223] w basr=0x10 csr=0x95 at start=1280

And this is from reading the file back:
[ 3799.053067] basr=0x10 csr=0xd5 at start=512
[ 3801.056337] basr=0x10 csr=0xd5 at start=3584
[ 3976.323836] scsi host2: 53C400r: host buffer not ready in time
[ 3976.404699] basr=0x10 csr=0xd5 at start=512
[ 3977.800647] basr=0x10 csr=0xd5 at start=512
[ 3979.240611] scsi host2: 53C400r: host buffer not ready in time
[ 3979.320698] basr=0x10 csr=0xd5 at start=512
[ 3980.040220] scsi host2: 53C400r: host buffer not ready in time
[ 3980.096401] basr=0x10 csr=0xd5 at start=512
[ 3980.394854] scsi host2: 53C400r: host buffer not ready in time


-- 
Ondrej Zary


Re: [PATCH v2 0/5] g_NCR5380: PDMA fixes and cleanup

2017-06-26 Thread Ondrej Zary
On Monday 26 June 2017, Finn Thain wrote:
> On Sun, 25 Jun 2017, Ondrej Zary wrote:
> > It mostly works, but there are some problems:
> >
> > It's not reliable - we continue the data transfer after poll_politely2
> > returns zero but we don't know if it returned because of host buffer
> > being ready of because of an IRQ. So if a device disconnects during
> > write, we continue to fill the buffer and only then find out that wait
> > for 53c80 registers timed out. Then PDMA gets disabled:
> > [ 3458.774251] sd 2:0:1:0: [sdb] tag#0 53c80 registers not accessible,
> > device will be reset [ 3458.774251] sd 2:0:1:0: [sdb] tag#0 switching to
> > slow handshake
>
> Sorry about that. I messed up the Gated-IRQ-is-asserted case when I
> changed the algorithm to avoid adding more polling loops.
>
> > We can just reset and continue with a new PDMA transfer.
>
> We should only reset the 53c400 logic when there is a real failure (like
> no access to 53c80 registers). If a reset is needed to handle normal
> target behaviour (like disconnection during a slow transfer) then we are
> doing something wrong.

The reset is probably the only way to terminate a PDMA transfer.

> > Found no problems with reads. But when this happens during a write, we
> > might have lost some data buffers that we need to transfer again. The
> > chip's PDMA block counter does not seem to be very helpful here -
> > testing shows that either one buffer is missing in the file or is
> > duplicated.
> >
> > That's why my code had separate host buffer ready and IRQ checks. Host
> > buffer first - if it's ready, transfer the data. If not, check for IRQ -
> > if it was an error, rollback 2 buffers (the same if the host buffer is
> > not ready in time).
>
> In v3 of the patch series I've fixed the Gated IRQ logic so the transfer
> loop will terminate early.
>
> > There's also a performance regression on DTC436 - the sg_tablesize limit
> > affects performance badly.
> > Before:
> > # hdparm -t --direct /dev/sdb
> >
> > /dev/sdb:
> >  Timing O_DIRECT disk reads:   4 MB in  3.21 seconds =   1.25 MB/sec
> >
> > Now:
> > # hdparm -t --direct /dev/sdb
> >
> > /dev/sdb:
> >  Timing O_DIRECT disk reads:   4 MB in  4.89 seconds = 837.69 kB/sec
>
> The lost throughput can perhaps be explained by extra kernel-mode CPU
> overhead. Next time maybe check for that with "time hdparm". Anyway, since
> you have a patch, we should try to avoid this regression.

I don't think the CPU is that slow. It probably decreases the SCSI read 
command length and we must wait for the drive to process each command (it 
probably does no read-ahead).

> > We should limit the transfer size instead:
> > --- a/drivers/scsi/g_NCR5380.c
> > +++ b/drivers/scsi/g_NCR5380.c
> > @@ -45,7 +45,8 @@
> > int c400_blk_cnt; \
> > int c400_host_buf; \
> > int io_width; \
> > -   int pdma_residual
> > +   int pdma_residual; \
> > +   int board;
> >
> >  #define NCR5380_dma_xfer_lengeneric_NCR5380_dma_xfer_len
> >  #define NCR5380_dma_recv_setup  generic_NCR5380_pread
> > @@ -247,7 +248,6 @@ static int generic_NCR5380_init_one(struct
> > scsi_host_template *tpnt, case BOARD_DTC3181E:
> > ports = dtc_3181e_ports;
> > magic = ncr_53c400a_magic;
> > -   tpnt->sg_tablesize = 1;
> > break;
> > }
>
> I've dropped my "sg_tablesize = 1" patch from the v3 series.
>
> > @@ -317,6 +317,7 @@ static int generic_NCR5380_init_one(struct
> > scsi_host_template *tpnt, }
> > hostdata = shost_priv(instance);
> >
> > +   hostdata->board = board;
> > hostdata->io = iomem;
> > hostdata->region_size = region_size;
>
> I've added the hostdata->board variable in v3. It looks like we are going
> to need it one way or another.
>
> > @@ -625,6 +626,9 @@ static int generic_NCR5380_dma_xfer_len(struct
> > NCR5380_hostdata *hostdata, /* 53C400 datasheet: non-modulo-128-byte
> > transfers should use PIO */ if (transfersize % 128)
> > transfersize = 0;
> > +   /* Limit transfers to 512B to prevent random write corruption on
> > DTC */ +   if (hostdata->board == BOARD_DTC3181E && transfersize >
> > 512) +   transfersize = 512;
> >
> > return min(transfersize, DMA_MAX_SIZE);
> >  }
> >
> >
> > No data corruption
>
> How did you confirm

Re: [PATCH v2 0/5] g_NCR5380: PDMA fixes and cleanup

2017-06-25 Thread Ondrej Zary
On Saturday 24 June 2017 08:37:36 Finn Thain wrote:
> Ondrej, would you please test this new series?
>
> Changed since v1:
> - PDMA transfer residual is calculated earlier.
> - End of DMA flag check is now polled (if there is any residual).
>
>
> Finn Thain (2):
>   g_NCR5380: Limit sg_tablesize to avoid PDMA read overruns on DTC436
>   g_NCR5380: Cleanup comments and whitespace
>
> Ondrej Zary (3):
>   g_NCR5380: Fix PDMA transfer size
>   g_NCR5380: End PDMA transfer correctly on target disconnection
>   g_NCR5380: Re-work PDMA loops
>
>  drivers/scsi/g_NCR5380.c | 231
> ++- 1 file changed, 107
> insertions(+), 124 deletions(-)

It mostly works, but there are some problems:

It's not reliable - we continue the data transfer after poll_politely2
returns zero but we don't know if it returned because of host buffer
being ready of because of an IRQ. So if a device disconnects during write,
we continue to fill the buffer and only then find out that wait for
53c80 registers timed out. Then PDMA gets disabled:
[ 3458.774251] sd 2:0:1:0: [sdb] tag#0 53c80 registers not accessible, device 
will be reset
[ 3458.774251] sd 2:0:1:0: [sdb] tag#0 switching to slow handshake

We can just reset and continue with a new PDMA transfer. Found no problems
with reads. But when this happens during a write, we might have lost some
data buffers that we need to transfer again. The chip's PDMA block counter
does not seem to be very helpful here - testing shows that either one buffer
is missing in the file or is duplicated.

That's why my code had separate host buffer ready and IRQ checks. Host
buffer first - if it's ready, transfer the data. If not, check for IRQ - 
if it was an error, rollback 2 buffers (the same if the host buffer is not
ready in time).



There's also a performance regression on DTC436 - the sg_tablesize limit
affects performance badly.
Before:
# hdparm -t --direct /dev/sdb

/dev/sdb:
 Timing O_DIRECT disk reads:   4 MB in  3.21 seconds =   1.25 MB/sec

Now:
# hdparm -t --direct /dev/sdb

/dev/sdb:
 Timing O_DIRECT disk reads:   4 MB in  4.89 seconds = 837.69 kB/sec

We should limit the transfer size instead:
--- a/drivers/scsi/g_NCR5380.c
+++ b/drivers/scsi/g_NCR5380.c
@@ -45,7 +45,8 @@
int c400_blk_cnt; \
int c400_host_buf; \
int io_width; \
-   int pdma_residual
+   int pdma_residual; \
+   int board;

 #define NCR5380_dma_xfer_lengeneric_NCR5380_dma_xfer_len
 #define NCR5380_dma_recv_setup  generic_NCR5380_pread
@@ -247,7 +248,6 @@ static int generic_NCR5380_init_one(struct 
scsi_host_template *tpnt,
case BOARD_DTC3181E:
ports = dtc_3181e_ports;
magic = ncr_53c400a_magic;
-   tpnt->sg_tablesize = 1;
break;
}

@@ -317,6 +317,7 @@ static int generic_NCR5380_init_one(struct 
scsi_host_template *tpnt,
}
hostdata = shost_priv(instance);

+   hostdata->board = board;
hostdata->io = iomem;
hostdata->region_size = region_size;

@@ -625,6 +626,9 @@ static int generic_NCR5380_dma_xfer_len(struct 
NCR5380_hostdata *hostdata,
/* 53C400 datasheet: non-modulo-128-byte transfers should use PIO */
if (transfersize % 128)
transfersize = 0;
+   /* Limit transfers to 512B to prevent random write corruption on DTC */
+   if (hostdata->board == BOARD_DTC3181E && transfersize > 512)
+   transfersize = 512;

return min(transfersize, DMA_MAX_SIZE);
 }


No data corruption and no performance regression:
# hdparm -t --direct /dev/sdb

/dev/sdb:
 Timing O_DIRECT disk reads:   4 MB in  3.25 seconds =   1.23 MB/sec

As the data corruption affects only writes, we could keep transfersize
unlimited for reads:
+   /* Limit write transfers to 512B to prevent random corruption on DTC */
+   if (hostdata->board == BOARD_DTC3181E &&
+   cmd->sc_data_direction == DMA_TO_DEVICE && transfersize > 512)
+   transfersize = 512;

So we can get some performance gain at least for reads:
# hdparm -t --direct /dev/sdb

/dev/sdb:
 Timing O_DIRECT disk reads:   6 MB in  4.17 seconds =   1.44 MB/sec


-- 
Ondrej Zary


Re: [PATCH 0/4] g_NCR5380: PDMA fixes and cleanup

2017-06-23 Thread Ondrej Zary
On Friday 23 June 2017 13:01:53 Finn Thain wrote:
> On Fri, 23 Jun 2017, I wrote:
> > Does this patch help? It should be applied on top of this series of 4.
>
> Sorry, I sent the wrong diff. Please try this patch instead.

Thanks, much better now: both HDD and CD-ROM seem to work on DTC and non-DTC 
chips. I get many of these messages with CD-ROM:
[  912.397076] generic_NCR5380_pread: No end dma signal (4096/4096)
[  913.141225] generic_NCR5380_pread: No end dma signal (4096/4096)

Maybe just remove this error message as in my original patch?

-- 
Ondrej Zary


Re: [PATCH 0/4] g_NCR5380: PDMA fixes and cleanup

2017-06-22 Thread Ondrej Zary
On Thursday 15 June 2017 14:17:56 Finn Thain wrote:
> Ondrej, would you please test this patch series? One of your patches
> has been modified slightly and the two I wrote are untested.

Works only with HDD on non-DTC chips. CD-ROM hangs. DTC hangs even with HDD.
The PDMA code really needs to be fixed.

-- 
Ondrej Zary


Re: g_NCR5380 PDMA, was Re: [PATCH 0/6] ncr5380: Miscellaneous minor patches

2017-02-19 Thread Ondrej Zary
On Sunday 19 February 2017 00:27:55 Finn Thain wrote:
> On Sat, 18 Feb 2017, Ondrej Zary wrote:
> > On Friday 17 February 2017 23:38:12 Finn Thain wrote:
> > > On Thu, 16 Feb 2017, Ondrej Zary wrote:
> > > > On Tuesday 31 January 2017 02:31:45 Finn Thain wrote:
> > > > [...]
> > > >
> > > > > Are you trying to figure out which commands are going to
> > > > > disconnect during a transfer? This is really a function of the
> > > > > firmware in the target; there are no good heuristics AFAICT, so
> > > > > the PDMA algorithm has to be robust. mac_scsi has to cope with
> > > > > this too.
> > > > >
> > > > > Does the problem go away when you assign no IRQ? When
> > > > > instance->irq == NO_IRQ, the core driver will inhibit disconnect
> > > > > privileges.
> > > >
> > > > Yes, it seems to run fine with IRQ/disconnect disabled. With IRQ
> > > > enabled, "dd if=/dev/sr0 of=anything" stops after a while.
> > >
> > > When you say "stops", do you mean an infinite loop in
> > > generic_NCR5380_pread or does the loop complete (which would
> > > presumably leave the target stuck in DATA IN phase, and a scsi command
> > > timeout would probably follow after 30 seconds...)
> >
> > I've added timeouts to the possibly-infinite loops. It times out waiting
> > for the host buffer to become ready.
>
> In mac_scsi you'll find that the PDMA loop exploits the 15ms poll_politely
> time limit to give the target device time to catch up. You might want to
> do something similar.
>
> > Then everything breaks. Now I found why: pread() returns without waiting
> > for the 53C80 registers to be ready.
>
> Ouch! You can't return control to the core driver when the 53C80 core is
> unavailable. That would need special handling: the core driver would have
> to fail the scsi command and reset the device (and bus), based on the
> result you return from NCR5380_dma_recv_setup/NCR5380_dma_send_setup.
>
> > Adding the wait allows to continue in PIO mode with "tag#0 switching to
> > slow handshake".
>
> I don't think this is the code path you want. The target isn't really
> broken. But yes, we could use PIO as a slow workaround for fragile PDMA
> logic.

Yes, we don't want that.

> > > > I get gated 53C80 IRQ, BASR=0x10, MODE=0x0e, STATUS=0x7c.
> > >
> > > You can use NCR5380_print() to get a decoded register dump.
> > >
> > > When I decode the above values I get,
> > >
> > > BASR   = 0x10 = BASR_IRQ
> > > MODE   = 0x0e = MR_ENABLE_EOP_INTR | MR_MONITOR_BSY | MR_DMA_MODE
> > > STATUS = 0x7c = SR_BSY | SR_REQ | SR_MSG | SR_CD | SR_IO
> > >
> > > Since BASR_PHASE_MATCH is not set, the interrupt is almost certainly a
> > > phase mismatch. The new phase is SR_MSG | SR_CD | SR_IO = PHASE_MSGIN,
> > > which shows that the target has given up on the DATA IN phase and is
> > > presumably trying to send a DISCONNECT message.
> >
> > Looks you're right. The transfersize is 4096, i.e. 2 CD-ROM sectors.
> > When the 2nd sector is not ready in the drive internal buffer, the drive
> > probably disconnects which breaks the fragile pdma transfer. When the
> > transfersize is limited to 2048 bytes, the problem goes away.
>
> OK.
>
> > The problem also went away with enabled interrupts because I had some
> > debug printks added which were slowing down the transfer enough for the
> > drive (SONY CDU-55S) to keep up and not disconnect. Got the same result
> > by inserting udelay(100) after each 128 byte block trasnferred in
> > pread().
>
> Well, yeah, if you change the timing and omit to mention that, as well as
> changing the spinlock_irq_save/restore pairs, then it's going to be
> difficult for me to make sense of your results. Anyway, I'm glad that you
> got to the bottom of this mystery.
>
> > > > When I enable interrupts during PDMA (like the removed UNSAFE macro
> > > > did), the problems go away. I see an IRQ after each pread call.

These two patches are enough to make PDMA work with CD-ROM drives on
53C400(A), with IRQ enabled or not. They even improve transfer rates with
HDDs because of bigger block size.

But DTC436 breaks with CDU-55S, immediately after modprobe.
1) Seems that IRQ timing is slightly different so I rewrote the wait for
the host buffer to include check for CSR_GATED_53C80_IRQ. This allows some
data to be transferred but
2) DTC436 likes to hang (return only 0xff from all registe

Re: g_NCR5380 PDMA, was Re: [PATCH 0/6] ncr5380: Miscellaneous minor patches

2017-02-18 Thread Ondrej Zary
On Friday 17 February 2017 23:38:12 Finn Thain wrote:
> On Thu, 16 Feb 2017, Ondrej Zary wrote:
> > On Tuesday 31 January 2017 02:31:45 Finn Thain wrote:
> > [...]
> >
> > > Are you trying to figure out which commands are going to disconnect
> > > during a transfer? This is really a function of the firmware in the
> > > target; there are no good heuristics AFAICT, so the PDMA algorithm has
> > > to be robust. mac_scsi has to cope with this too.
> > >
> > > Does the problem go away when you assign no IRQ? When instance->irq ==
> > > NO_IRQ, the core driver will inhibit disconnect privileges.
> >
> > Yes, it seems to run fine with IRQ/disconnect disabled. With IRQ
> > enabled, "dd if=/dev/sr0 of=anything" stops after a while.
>
> When you say "stops", do you mean an infinite loop in
> generic_NCR5380_pread or does the loop complete (which would presumably
> leave the target stuck in DATA IN phase, and a scsi command timeout would
> probably follow after 30 seconds...)

I've added timeouts to the possibly-infinite loops. It times out waiting for 
the host buffer to become ready. Then everything breaks.
Now I found why: pread() returns without waiting for the 53C80 registers to be 
ready. Adding the wait allows to continue in PIO mode with "tag#0 switching 
to slow handshake".

> > I get gated 53C80 IRQ, BASR=0x10, MODE=0x0e, STATUS=0x7c.
>
> You can use NCR5380_print() to get a decoded register dump.
>
> When I decode the above values I get,
>
> BASR   = 0x10 = BASR_IRQ
> MODE   = 0x0e = MR_ENABLE_EOP_INTR | MR_MONITOR_BSY | MR_DMA_MODE
> STATUS = 0x7c = SR_BSY | SR_REQ | SR_MSG | SR_CD | SR_IO
>
> Since BASR_PHASE_MATCH is not set, the interrupt is almost certainly a
> phase mismatch. The new phase is SR_MSG | SR_CD | SR_IO = PHASE_MSGIN,
> which shows that the target has given up on the DATA IN phase and is
> presumably trying to send a DISCONNECT message.

Looks you're right. The transfersize is 4096, i.e. 2 CD-ROM sectors. When the 
2nd sector is not ready in the drive internal buffer, the drive probably 
disconnects which breaks the fragile pdma transfer. When the transfersize is 
limited to 2048 bytes, the problem goes away.

The problem also went away with enabled interrupts because I had some debug 
printks added which were slowing down the transfer enough for the drive (SONY 
CDU-55S) to keep up and not disconnect. Got the same result by inserting 
udelay(100) after each 128 byte block trasnferred in pread().

> > When I enable interrupts during PDMA (like the removed UNSAFE macro
> > did), the problems go away. I see an IRQ after each pread call.
>
> You shouldn't need an interrupt, because NCR5380_dma_complete() gets
> called regardless. AFAICT, the only difference is the timing, which
> becomes less predictable. Calling spinlock_irq_restore() before the
> transfer seems to create a race condition between hostdata->dma_len store
> and load.
>
> I think that the pread call has not yet returned when the interrupt fires
> and NCR5380_dma_complete() is called. Hence hostdata->dma_len has not yet
> been initialized. So when NCR5380_dma_complete() is called by the
> interrupt handler, SCp.this_residual will not change at all because
> hostdata->dma_len is still zero.
>
> > (had to disable "no 53C80 gated irq after transfer" and "no end dma
> > signal" messages to reduce log spam)
>
> That may provide a quick way to detect the failed PDMA transfer, at least
> for testing purposes. There may be a more conclusive test for a partial
> transfer.
>
> We could to implement something like macscsi_dma_residual() to take care
> of a failed PDMA transfer. That way, the failure can be taken into account
> when NCR5380_dma_complete() is called at the end of the transfer.
>
> See patch below for example. It should confirm the theory above though it
> really needs some timeouts added (NCR5380_poll_politely()). And perhaps we
> could do something more clever than retry indefinitely, though we can
> still rely on the command timeout.

Thanks for idea

> diff --git a/drivers/scsi/g_NCR5380.c b/drivers/scsi/g_NCR5380.c
> index 6f9665d..75cfaf3 100644
> --- a/drivers/scsi/g_NCR5380.c
> +++ b/drivers/scsi/g_NCR5380.c
> @@ -497,15 +497,17 @@ static inline int generic_NCR5380_pread(struct
> NCR5380_hostdata *hostdata, blocks--;
>   }
>
> + hostdata->pdma_residual = 0;
> +
>   if (!(NCR5380_read(hostdata->c400_ctl_status) & CSR_GATED_53C80_IRQ))
> - printk("53C400r: no 53C80 gated irq after transfer");
> + hostdata->pdma_residual = hostdata->dma_len;
>
>   /* wait for 53C80 registe

Re: g_NCR5380 PDMA, was Re: [PATCH 0/6] ncr5380: Miscellaneous minor patches

2017-02-16 Thread Ondrej Zary
On Tuesday 31 January 2017 02:31:45 Finn Thain wrote:
[...]
> Are you trying to figure out which commands are going to disconnect during
> a transfer? This is really a function of the firmware in the target; there
> are no good heuristics AFAICT, so the PDMA algorithm has to be robust.
> mac_scsi has to cope with this too.
>
> Does the problem go away when you assign no IRQ? When instance->irq ==
> NO_IRQ, the core driver will inhibit disconnect privileges.

Yes, it seems to run fine with IRQ/disconnect disabled.
With IRQ enabled, "dd if=/dev/sr0 of=anything" stops after a while. I get 
gated 53C80 IRQ, BASR=0x10, MODE=0x0e, STATUS=0x7c.

When I enable interrupts during PDMA (like the removed UNSAFE macro did), the 
problems go away. I see an IRQ after each pread call.
(had to disable "no 53C80 gated irq after transfer" and "no end dma signal" 
messages to reduce log spam)

-- 
Ondrej Zary


Re: [PATCH 0/6] ncr5380: Miscellaneous minor patches

2017-01-30 Thread Ondrej Zary
On Sunday 29 January 2017 02:05:02 Finn Thain wrote:
> On Sat, 28 Jan 2017, Ondrej Zary wrote:
> > On Monday 16 January 2017 00:50:57 Finn Thain wrote:
> > > This series removes some unused code and related comments, addresses
> > > the warnings generated by 'make W=1' and 'make C=1' and fixes a
> > > theoretical bug in the bus reset method in atari_scsi.
> > >
> > > There's also a patch to add a missing error check during target
> > > selection. The only target I tested was a QUANTUM DAYTONA514S disk as
> > > that's all I have access to right now. Some testing with other targets
> > > would be prudent.
> > >
> > > Michael, Ondrej, can I get you to review/test please?
> >
> > Tested on HP C2502 (53C400A chip), Canon FG2-5202 (53C400 chip),
> > DTC-3181L (DTCT-436P chip) and MS-PNR (53C400A chip) ISA cards -
> > everything works fine!
> >
> > Targets tested:
> > QUANTUM  LP240S GM240S01X
> > IBM  DORS-32160
> > IBM  0663L12
> >
> > Thanks.
> >
> > Tested-by: Ondrej Zary 
>
> Very helpful. Thank you, Ondrej.

Also tested two CD-ROM drives and they didn't work (machine hangs). They
didn't work before and looks like they never worked with PDMA.

The fundamental problem of PDMA is that it either transfers all required data
or it breaks horribly. Even when I added timeouts to the possibly infinite
loops (to avoid hangs), the chip remained in some bad state. Sometimes the
53C80 gated IRQ check triggers. This can be hopefully fixed but there is a HW
limitation: if less than 128 bytes were read from SCSI device, they get lost
in chip buffer (the 128B buffers don't swap until full).

Fortunately, most of the requests for too much data are bogus. The problem is
that generic_NCR5380_dma_xfer_len() uses cmd->transfersize which seems to be
wrong. All other NCR5380 drivers use cmd->SCp.this_residual.

This is also why rescan-scsi-bus hangs (cmd->transfersize is 8192 but
cmd->SCp.this_residual is only 96).

This quick fix allows CD-ROM and also rescan-scsi-bus to work.
But it's not complete. Seems that we need:
 - fix pread and pwrite to terminate gracefully
 - something like atari_scsi_dma_xfer_len to allow DMA only for block commands

@@ -588,22 +619,19 @@ static inline int generic_NCR5380_pwrite(struct 
NCR5380_hostdata *hostdata,
 static int generic_NCR5380_dma_xfer_len(struct NCR5380_hostdata *hostdata,
 struct scsi_cmnd *cmd)
 {
-   int transfersize = cmd->transfersize;
+   int transfersize = cmd->SCp.this_residual;

if (hostdata->flags & FLAG_NO_PSEUDO_DMA)
return 0;

-   /* 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;
-
/* 53C400 datasheet: non-modulo-128-byte transfers should use PIO */
if (transfersize % 128)
transfersize = 0;

+   /* Limit transfers to 32K */
+   if (transfersize > 32 * 1024)
+   transfersize = 32 * 1024;
+
return transfersize;
 }




-- 
Ondrej Zary
--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 0/6] ncr5380: Miscellaneous minor patches

2017-01-28 Thread Ondrej Zary
On Monday 16 January 2017 00:50:57 Finn Thain wrote:
> This series removes some unused code and related comments,
> addresses the warnings generated by 'make W=1' and 'make C=1'
> and fixes a theoretical bug in the bus reset method in atari_scsi.
>
> There's also a patch to add a missing error check during target
> selection. The only target I tested was a QUANTUM DAYTONA514S disk
> as that's all I have access to right now. Some testing with other
> targets would be prudent.
>
> Michael, Ondrej, can I get you to review/test please?

Tested on HP C2502 (53C400A chip), Canon FG2-5202 (53C400 chip), DTC-3181L 
(DTCT-436P chip) and MS-PNR (53C400A chip) ISA cards - everything works fine!

Targets tested:
QUANTUM  LP240S GM240S01X
IBM  DORS-32160
IBM  0663L12

Thanks.

Tested-by: Ondrej Zary 

-- 
Ondrej Zary
--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 0/4] g_NCR5380: Bug fix and some enhancements

2016-12-08 Thread Ondrej Zary
On Monday 05 December 2016 07:07:19 Finn Thain wrote:
> This patch series is based on the one submitted recently by Ondrej Zary.
>
> This version has a different irq probing fix for HP C2502 boards and
> a more comprehensive patch to change the default irq parameter.
>
> It needs testing on actual ISA hardware.

Tested on HP C2502 (53C400A chip), Canon FG2-5202 (53C400 chip), DTC-3181L 
(DTCT-436P chip) and MS-PNR (53C400A chip) ISA cards - everything works fine!

Thanks.

Tested-by: Ondrej Zary 

BTW. The release-region fix (my previous patch 6/6) has disappeared somehow. 
Should I resubmit?

-- 
Ondrej Zary
--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 4/6] g_NCR5380: Add IRQ auto-configuration for HP C2502

2016-11-03 Thread Ondrej Zary
On Thursday 03 November 2016, Finn Thain wrote:
> On Wed, 2 Nov 2016, Ondrej Zary wrote:
> > > Also, you've ignored the irq module parameters. From the user's point
> > > of view, surely the least surprising thing is to attempt to configure
> > > the card for whatever irq the user asked for.
> >
> > I haven't. NCR5380_find_irq is only called when irq is set to IRQ_AUTO.
>
> My mistake.
>
> > > If the specified irq isn't supported by the board, just log an error
> > > and fail. If you want to be user friendly, print a message to tell
> > > them what irqs the card supports.
> >
> > If the IRQ is not supported (or does not work), user gets a warning and
> > the driver continues with IRQ disabled.
> >
> > > If the user asks for IRQ_AUTO, just configure the board for a
> > > hard-coded default, say 9, and print a warning message to say so.
> >
> > The card is almost Plug&Play. The base address is already configured
> > automatically by the driver so doing the same for IRQ makes sense.
>
> Why don't we see any other drivers doing this?

Many ISA sound card drivers do this - there's even a function for this:
static int snd_legacy_find_free_irq(int *irq_table)

Unfortunately, it's defined in ALSA headers and even protected with an #ifdef.

> If the card was really plug and play, I expect we would just call
> pnp_irq(), as the other PNP drivers do.

The card predates the PnP standard so we can't.

> > > Either way, if request_irq fails just continue with NO_IRQ, as per
> > > usual.
> > >
> > > To me that's the most flexible and least surprising behaviour. But
> > > again, if someone with more ISA knowledge wishes to weigh in, that's
> > > fine too.



-- 
Ondrej Zary
--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 2/6] g_NCR5380: Test the IRQ before accepting it

2016-11-02 Thread Ondrej Zary
On Wednesday 02 November 2016 08:45:26 Finn Thain wrote:
> On Mon, 31 Oct 2016, Ondrej Zary wrote:
> > Trigger an IRQ first with a test IRQ handler to find out if it really
> > works. Disable the IRQ if not.
> >
> > This prevents hang when incorrect IRQ was specified by user.
>
> Once again, how does it cause a hang?

Kernel scans the bus, finds a HDD, then attempts to read MBR. modprobe process 
is stuck but the system is still running. Then the transfer probably times 
out and everything locks up hard, even fbcon cursor stops blinking. I guess 
that kernel is trying to abort or reset.
BTW. rescan-scsi-bus also causes hang, anytime, even without IRQ.

> If the user specifies an IRQ, we should trust them. If they don't specify
> an IRQ then probe (as in patch 5/6).
>
> > Signed-off-by: Ondrej Zary 
> > ---
> >  drivers/scsi/g_NCR5380.c |   44
> > +--- 1 file changed, 41
> > insertions(+), 3 deletions(-)
> >
> > diff --git a/drivers/scsi/g_NCR5380.c b/drivers/scsi/g_NCR5380.c
> > index 09c660b..0d1f6ad 100644
> > --- a/drivers/scsi/g_NCR5380.c
> > +++ b/drivers/scsi/g_NCR5380.c
> > @@ -115,6 +115,32 @@ static int NCR5380_probe_irq(struct Scsi_Host
> > *instance) return irq;
> >  }
> >
> > +static bool irq_working;
> > +
> > +static irqreturn_t test_irq(int irq, void *dev_id)
> > +{
> > +   irq_working = true;
> > +   return IRQ_HANDLED;
> > +}
> > +
> > +/* test if the IRQ is working */
> > +static int NCR5380_test_irq(struct Scsi_Host *instance, int irq)
> > +{
> > +   struct NCR5380_hostdata *hostdata = shost_priv(instance);
> > +
> > +   irq_working = false;
> > +   if (request_irq(irq, test_irq, 0, "NCR5380-irqtest", NULL))
> > +   return -EBUSY;
> > +   NCR5380_trigger_irq(instance);
> > +   NCR5380_read(RESET_PARITY_INTERRUPT_REG);
> > +   free_irq(irq, NULL);
> > +
> > +   if (!irq_working)
> > +   return -EIO;
> > +
> > +   return 0;
> > +}
> > +
>
> IMO the extra complexity is not justified by the possibility of machines
> with misconfigured BIOS or incorrect module parameters.
>
> I don't want another irq probing mechanism. We just got rid of one.
>
> But I won't mind if the SCSI maintainers who know ISA better than I do
> would like to review this.
>
> >  /*
> >   * Configure I/O address of 53C400A or DTC436 by writing magic numbers
> >   * to ports 0x779 and 0x379.
> > @@ -323,9 +349,21 @@ static int generic_NCR5380_init_one(struct
> > scsi_host_template *tpnt, /* set IRQ for HP C2502 */
> > if (board == BOARD_HP_C2502)
> > magic_configure(port_idx, instance->irq, magic);
> > -   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); +ret = 
> > NCR5380_test_irq(instance,
> > instance->irq);
> > +   if (ret) {
> > +   printk(KERN_WARNING "scsi%d : IRQ%d not %s, interrupts 
> > disabled\n",
> > +  instance->host_no, instance->irq,
> > +  (ret == -EBUSY) ? "free" : "working");
> > +       instance->irq = NO_IRQ;
> > +   }
> > +   }
> > +
> > +   if (instance->irq != NO_IRQ) {
> > +   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;
> > }
> > }


-- 
Ondrej Zary
--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 4/6] g_NCR5380: Add IRQ auto-configuration for HP C2502

2016-11-02 Thread Ondrej Zary
On Wednesday 02 November 2016, Finn Thain wrote:
> On Mon, 31 Oct 2016, Ondrej Zary wrote:
> > Find free and working IRQ automatically on HP C2502 cards.
> > Also allow IRQ 9 to work (aliases to IRQ 2 on the card).
> >
> > Signed-off-by: Ondrej Zary 
> > ---
> >  drivers/scsi/g_NCR5380.c |   29 +++--
> >  1 file changed, 27 insertions(+), 2 deletions(-)
> >
> > diff --git a/drivers/scsi/g_NCR5380.c b/drivers/scsi/g_NCR5380.c
> > index e713dba..27fc499 100644
> > --- a/drivers/scsi/g_NCR5380.c
> > +++ b/drivers/scsi/g_NCR5380.c
> > @@ -156,6 +156,8 @@ static void magic_configure(int idx, u8 irq, u8
> > magic[]) outb(magic[4], 0x379);
> >
> > /* allowed IRQs for HP C2502 */
> > +   if (irq == 9)
> > +   irq = 2;
> > if (irq != 2 && irq != 3 && irq != 4 && irq != 5 && irq != 7)
> > irq = 0;
> > if (idx >= 0 && idx <= 7)
> > @@ -163,6 +165,21 @@ static void magic_configure(int idx, u8 irq, u8
> > magic[]) outb(cfg, 0x379);
> >  }
> >
> > +/* find a free and working IRQ (for HP C2502) */
> > +static int NCR5380_find_irq(struct Scsi_Host *instance, u8 irqs[],
> > +   int port_idx, u8 magic[])
> > +{
> > +   int i;
> > +
> > +   for (i = 0; irqs[i]; i++) {
> > +   magic_configure(port_idx, irqs[i], magic);
> > +   if (NCR5380_test_irq(instance, irqs[i]) == 0)
> > +   return irqs[i];
>
> The NCR5380_test_irq routine in patch 2/6 doesn't work for shared irqs, so
> you may not get the IRQ you would expect. (The core driver does support
> shared irqs, BTW.)

ISA bus does not support IRQ sharing.

> Also, you've ignored the irq module parameters. From the user's point of
> view, surely the least surprising thing is to attempt to configure the
> card for whatever irq the user asked for.

I haven't. NCR5380_find_irq is only called when irq is set to IRQ_AUTO.

> If the specified irq isn't supported by the board, just log an error and
> fail. If you want to be user friendly, print a message to tell them what
> irqs the card supports.

If the IRQ is not supported (or does not work), user gets a warning and the 
driver continues with IRQ disabled.

> If the user asks for IRQ_AUTO, just configure the board for a hard-coded
> default, say 9, and print a warning message to say so.

The card is almost Plug&Play. The base address is already configured 
automatically by the driver so doing the same for IRQ makes sense.

> Either way, if request_irq fails just continue with NO_IRQ, as per usual.
>
> To me that's the most flexible and least surprising behaviour. But again,
> if someone with more ISA knowledge wishes to weigh in, that's fine too.
>
> > +   }
> > +   magic_configure(port_idx, 0, magic);
> > +   return NO_IRQ;
> > +}
> > +
> >  static unsigned int ncr_53c400a_ports[] = {
> > 0x280, 0x290, 0x300, 0x310, 0x330, 0x340, 0x348, 0x350, 0
> >  };
> > @@ -175,6 +192,9 @@ static void magic_configure(int idx, u8 irq, u8
> > magic[]) static u8 hp_c2502_magic[] = { /* HP C2502 */
> > 0x0f, 0x22, 0xf0, 0x20, 0x80
> >  };
> > +static u8 hp_c2502_irqs[] = {
> > +   9, 5, 7, 3, 4, 0
> > +};
> >
> >  static int generic_NCR5380_init_one(struct scsi_host_template *tpnt,
> > struct device *pdev, int base, int irq, int board)
> > @@ -345,8 +365,13 @@ static int generic_NCR5380_init_one(struct
> > scsi_host_template *tpnt,
> >
> > if (irq != IRQ_AUTO)
> > instance->irq = irq;
> > -   else
> > -   instance->irq = NCR5380_probe_irq(instance);
> > +   else {
> > +   if (board == BOARD_HP_C2502)
> > +   instance->irq = NCR5380_find_irq(instance,
> > +   hp_c2502_irqs, port_idx, magic);
> > +   else
> > +   instance->irq = NCR5380_probe_irq(instance);
> > +   }
> >
> > /* Compatibility with documented NCR5380 kernel parameters */
> > if (instance->irq == 255)



-- 
Ondrej Zary
--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 1/6] NCR5380: Use probe_irq_*() for IRQ probing

2016-11-02 Thread Ondrej Zary
On Wednesday 02 November 2016, Finn Thain wrote:
> On Mon, 31 Oct 2016, Ondrej Zary wrote:
> > Use standard probe_irq_on() and probe_irq_off() functions instead of own
> > implementation. This prevents warning messages like this in the kernel
> > log: genirq: Flags mismatch irq 1.  (NCR-probe) vs. 0080
> > (i8042)
> >
> > Move the IRQ trigger code to a separate function so it can be used for
> > other purposes (testing if the IRQ works) and move the code from NCR5380
> > to g_NCR5380.
> >
> > Also add missing IRQ reset before and after the probe.
> >
> > Signed-off-by: Ondrej Zary 
> > ---
> >  drivers/scsi/NCR5380.c   |   77
> > +- drivers/scsi/NCR5380.h   |
> >1 -
> >  drivers/scsi/g_NCR5380.c |   50 +-
> >  3 files changed, 50 insertions(+), 78 deletions(-)
> >
> > diff --git a/drivers/scsi/NCR5380.c b/drivers/scsi/NCR5380.c
> > index d849ffa..4f5ca79 100644
> > --- a/drivers/scsi/NCR5380.c
> > +++ b/drivers/scsi/NCR5380.c
> > @@ -97,9 +97,6 @@
> >   * 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.
> > - *
> >   * AUTOSENSE - if defined, REQUEST SENSE will be performed automatically
> >   * for commands that return with a CHECK CONDITION status.
> >   *
> > @@ -127,9 +124,7 @@
> >   * NCR5380_dma_residual   - residual byte count
> >   *
> >   * The generic driver is initialized by calling NCR5380_init(instance),
> > - * after setting the appropriate host specific fields and ID.  If the
> > - * driver wishes to autoprobe for an IRQ line, the
> > NCR5380_probe_irq(instance, - * possible) function may be used.
> > + * after setting the appropriate host specific fields and ID.
> >   */
> >
> >  #ifndef NCR5380_io_delay
> > @@ -351,76 +346,6 @@ static void NCR5380_print_phase(struct Scsi_Host
> > *instance) }
> >  #endif
> >
> > -
> > -static int probe_irq;
> > -
> > -/**
> > - * 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.
> > - */
> > -
> > -static irqreturn_t probe_intr(int irq, void *dev_id)
> > -{
> > -   probe_irq = irq;
> > -   return IRQ_HANDLED;
> > -}
> > -
> > -/**
> > - * 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.
> > - */
> > -
> > -static int __maybe_unused NCR5380_probe_irq(struct Scsi_Host *instance,
> > -   int possible)
> > -{
> > -   struct NCR5380_hostdata *hostdata = shost_priv(instance);
> > -   unsigned long timeout;
> > -   int trying_irqs, i, mask;
> > -
> > -   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)) -  trying_irqs |= mask;
> > -
> > -   timeout = jiffies + msecs_to_jiffies(250);
> > -   probe_irq = NO_IRQ;
> > -
> > -   /*
> > -* A interrupt is triggered whenever BSY = false, SEL = true
> > -* 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
> > -* (I/O, C/D, and MSG) match those in the TCR, so we must reset that
> > -* to zero.
> > -*/
> > -
> > -   NCR5380_write(TARGET_COMMAND_REG, 0);
> > -   NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
> > -   NCR5380_write(OUTPUT_DATA_REG, hostdata->id_mask);
> > -   NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_DATA |
> > ICR_ASSERT_SEL); -
> > -   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);
> > -
> > -   for (i = 1, mask = 2; i < 16; ++i, 

[PATCH 2/6] g_NCR5380: Test the IRQ before accepting it

2016-10-31 Thread Ondrej Zary
Trigger an IRQ first with a test IRQ handler to find out if it really
works. Disable the IRQ if not.

This prevents hang when incorrect IRQ was specified by user.

Signed-off-by: Ondrej Zary 
---
 drivers/scsi/g_NCR5380.c |   44 +---
 1 file changed, 41 insertions(+), 3 deletions(-)

diff --git a/drivers/scsi/g_NCR5380.c b/drivers/scsi/g_NCR5380.c
index 09c660b..0d1f6ad 100644
--- a/drivers/scsi/g_NCR5380.c
+++ b/drivers/scsi/g_NCR5380.c
@@ -115,6 +115,32 @@ static int NCR5380_probe_irq(struct Scsi_Host *instance)
return irq;
 }
 
+static bool irq_working;
+
+static irqreturn_t test_irq(int irq, void *dev_id)
+{
+   irq_working = true;
+   return IRQ_HANDLED;
+}
+
+/* test if the IRQ is working */
+static int NCR5380_test_irq(struct Scsi_Host *instance, int irq)
+{
+   struct NCR5380_hostdata *hostdata = shost_priv(instance);
+
+   irq_working = false;
+   if (request_irq(irq, test_irq, 0, "NCR5380-irqtest", NULL))
+   return -EBUSY;
+   NCR5380_trigger_irq(instance);
+   NCR5380_read(RESET_PARITY_INTERRUPT_REG);
+   free_irq(irq, NULL);
+
+   if (!irq_working)
+   return -EIO;
+
+   return 0;
+}
+
 /*
  * Configure I/O address of 53C400A or DTC436 by writing magic numbers
  * to ports 0x779 and 0x379.
@@ -323,9 +349,21 @@ static int generic_NCR5380_init_one(struct 
scsi_host_template *tpnt,
/* set IRQ for HP C2502 */
if (board == BOARD_HP_C2502)
magic_configure(port_idx, instance->irq, magic);
-   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);
+   ret = NCR5380_test_irq(instance, instance->irq);
+   if (ret) {
+   printk(KERN_WARNING "scsi%d : IRQ%d not %s, interrupts 
disabled\n",
+  instance->host_no, instance->irq,
+  (ret == -EBUSY) ? "free" : "working");
+   instance->irq = NO_IRQ;
+   }
+   }
+
+   if (instance->irq != NO_IRQ) {
+   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;
}
}
-- 
Ondrej Zary

--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 0/6] (g_)NCR5380: Improve IRQ probing and some fixes

2016-10-31 Thread Ondrej Zary
Hello,
this patch series improves IRQ probing and moves it from NCR5380 to
g_NCR5380, adds IRQ auto-configuration for HP C2502 and enables all
this by default. It also adds IRQ and base address checks to prevent
hangs when wrong values are specified by user. There's also a small
release region fix in error handling.

--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 3/6] g_NCR5380: Check for chip presence before calling NCR5380_init()

2016-10-31 Thread Ondrej Zary
Write and read back MODE_REG to check if the chip is really there
before doing more initialization.

This prevents hang when incorrect I/O address was specified by user (in
the most common case where no device is present there so all reads
result in 0xff).

Signed-off-by: Ondrej Zary 
---
 drivers/scsi/g_NCR5380.c |7 +++
 1 file changed, 7 insertions(+)

diff --git a/drivers/scsi/g_NCR5380.c b/drivers/scsi/g_NCR5380.c
index 0d1f6ad..e713dba 100644
--- a/drivers/scsi/g_NCR5380.c
+++ b/drivers/scsi/g_NCR5380.c
@@ -322,6 +322,13 @@ static int generic_NCR5380_init_one(struct 
scsi_host_template *tpnt,
}
}
 
+   /* check if the chip is really there */
+   NCR5380_write(MODE_REG, 0);
+   if (NCR5380_read(MODE_REG) != 0) {
+   ret = -ENODEV;
+   goto out_unregister;
+   }
+
ret = NCR5380_init(instance, flags | FLAG_LATE_DMA_SETUP);
if (ret)
goto out_unregister;
-- 
Ondrej Zary

--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 4/6] g_NCR5380: Add IRQ auto-configuration for HP C2502

2016-10-31 Thread Ondrej Zary
Find free and working IRQ automatically on HP C2502 cards.
Also allow IRQ 9 to work (aliases to IRQ 2 on the card).

Signed-off-by: Ondrej Zary 
---
 drivers/scsi/g_NCR5380.c |   29 +++--
 1 file changed, 27 insertions(+), 2 deletions(-)

diff --git a/drivers/scsi/g_NCR5380.c b/drivers/scsi/g_NCR5380.c
index e713dba..27fc499 100644
--- a/drivers/scsi/g_NCR5380.c
+++ b/drivers/scsi/g_NCR5380.c
@@ -156,6 +156,8 @@ static void magic_configure(int idx, u8 irq, u8 magic[])
outb(magic[4], 0x379);
 
/* allowed IRQs for HP C2502 */
+   if (irq == 9)
+   irq = 2;
if (irq != 2 && irq != 3 && irq != 4 && irq != 5 && irq != 7)
irq = 0;
if (idx >= 0 && idx <= 7)
@@ -163,6 +165,21 @@ static void magic_configure(int idx, u8 irq, u8 magic[])
outb(cfg, 0x379);
 }
 
+/* find a free and working IRQ (for HP C2502) */
+static int NCR5380_find_irq(struct Scsi_Host *instance, u8 irqs[],
+   int port_idx, u8 magic[])
+{
+   int i;
+
+   for (i = 0; irqs[i]; i++) {
+   magic_configure(port_idx, irqs[i], magic);
+   if (NCR5380_test_irq(instance, irqs[i]) == 0)
+   return irqs[i];
+   }
+   magic_configure(port_idx, 0, magic);
+   return NO_IRQ;
+}
+
 static unsigned int ncr_53c400a_ports[] = {
0x280, 0x290, 0x300, 0x310, 0x330, 0x340, 0x348, 0x350, 0
 };
@@ -175,6 +192,9 @@ static void magic_configure(int idx, u8 irq, u8 magic[])
 static u8 hp_c2502_magic[] = { /* HP C2502 */
0x0f, 0x22, 0xf0, 0x20, 0x80
 };
+static u8 hp_c2502_irqs[] = {
+   9, 5, 7, 3, 4, 0
+};
 
 static int generic_NCR5380_init_one(struct scsi_host_template *tpnt,
struct device *pdev, int base, int irq, int board)
@@ -345,8 +365,13 @@ static int generic_NCR5380_init_one(struct 
scsi_host_template *tpnt,
 
if (irq != IRQ_AUTO)
instance->irq = irq;
-   else
-   instance->irq = NCR5380_probe_irq(instance);
+   else {
+   if (board == BOARD_HP_C2502)
+   instance->irq = NCR5380_find_irq(instance,
+   hp_c2502_irqs, port_idx, magic);
+   else
+   instance->irq = NCR5380_probe_irq(instance);
+   }
 
/* Compatibility with documented NCR5380 kernel parameters */
if (instance->irq == 255)
-- 
Ondrej Zary

--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 1/6] NCR5380: Use probe_irq_*() for IRQ probing

2016-10-31 Thread Ondrej Zary
Use standard probe_irq_on() and probe_irq_off() functions instead of
own implementation.
This prevents warning messages like this in the kernel log:
genirq: Flags mismatch irq 1.  (NCR-probe) vs. 0080 (i8042)

Move the IRQ trigger code to a separate function so it can be used for
other purposes (testing if the IRQ works) and move the code from
NCR5380 to g_NCR5380.

Also add missing IRQ reset before and after the probe.

Signed-off-by: Ondrej Zary 
---
 drivers/scsi/NCR5380.c   |   77 +-
 drivers/scsi/NCR5380.h   |1 -
 drivers/scsi/g_NCR5380.c |   50 +-
 3 files changed, 50 insertions(+), 78 deletions(-)

diff --git a/drivers/scsi/NCR5380.c b/drivers/scsi/NCR5380.c
index d849ffa..4f5ca79 100644
--- a/drivers/scsi/NCR5380.c
+++ b/drivers/scsi/NCR5380.c
@@ -97,9 +97,6 @@
  * 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.
- *
  * AUTOSENSE - if defined, REQUEST SENSE will be performed automatically
  * for commands that return with a CHECK CONDITION status.
  *
@@ -127,9 +124,7 @@
  * NCR5380_dma_residual   - residual byte count
  *
  * The generic driver is initialized by calling NCR5380_init(instance),
- * after setting the appropriate host specific fields and ID.  If the
- * driver wishes to autoprobe for an IRQ line, the NCR5380_probe_irq(instance,
- * possible) function may be used.
+ * after setting the appropriate host specific fields and ID.
  */
 
 #ifndef NCR5380_io_delay
@@ -351,76 +346,6 @@ static void NCR5380_print_phase(struct Scsi_Host *instance)
 }
 #endif
 
-
-static int probe_irq;
-
-/**
- * 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.
- */
-
-static irqreturn_t probe_intr(int irq, void *dev_id)
-{
-   probe_irq = irq;
-   return IRQ_HANDLED;
-}
-
-/**
- * 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.
- */
-
-static int __maybe_unused NCR5380_probe_irq(struct Scsi_Host *instance,
-   int possible)
-{
-   struct NCR5380_hostdata *hostdata = shost_priv(instance);
-   unsigned long timeout;
-   int trying_irqs, i, mask;
-
-   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))
-   trying_irqs |= mask;
-
-   timeout = jiffies + msecs_to_jiffies(250);
-   probe_irq = NO_IRQ;
-
-   /*
-* A interrupt is triggered whenever BSY = false, SEL = true
-* 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
-* (I/O, C/D, and MSG) match those in the TCR, so we must reset that
-* to zero.
-*/
-
-   NCR5380_write(TARGET_COMMAND_REG, 0);
-   NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
-   NCR5380_write(OUTPUT_DATA_REG, hostdata->id_mask);
-   NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_DATA | 
ICR_ASSERT_SEL);
-
-   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);
-
-   for (i = 1, mask = 2; i < 16; ++i, mask <<= 1)
-   if (trying_irqs & mask)
-   free_irq(i, NULL);
-
-   return probe_irq;
-}
-
 /**
  * NCR58380_info - report driver and host information
  * @instance: relevant scsi host instance
diff --git a/drivers/scsi/NCR5380.h b/drivers/scsi/NCR5380.h
index 3c6ce54..4724558 100644
--- a/drivers/scsi/NCR5380.h
+++ b/drivers/scsi/NCR5380.h
@@ -290,7 +290,6 @@ static inline struct scsi_cmnd *NCR5380_to_scmd(struct 
NCR5380_cmd *ncmd_ptr)
 #define NCR5380_dprint_phase(flg, arg) do {} while (0)
 #endif
 
-static int NCR5380_probe_irq(struct Scsi_Host *instance, int possible);
 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);
diff --git a/drivers/scsi/g_NCR5380.c b/drivers/scsi/g_NCR5380.c
index 7299ad9..09c660b 100644
--- a/drivers/scsi/g_NCR5380.c
+++ b/drivers/scsi/g_NCR5380.c
@@ -67,6 +67,54 @@
 MODULE_ALIAS("g_NCR5380_mmio");
 MODULE_LICENSE("GPL");
 
+static void NCR5380_trigger_irq(struct Scsi_

[PATCH 5/6] g_NCR5380: Autoprobe IRQ by default

2016-10-31 Thread Ondrej Zary
IRQ probing seems to work fine now. Default to autoprobe for IRQ instead
of disabling it.

Signed-off-by: Ondrej Zary 
---
 drivers/scsi/g_NCR5380.c |4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/scsi/g_NCR5380.c b/drivers/scsi/g_NCR5380.c
index 27fc499..6a08d3e 100644
--- a/drivers/scsi/g_NCR5380.c
+++ b/drivers/scsi/g_NCR5380.c
@@ -52,9 +52,9 @@
 module_param(dtc_3181e, int, 0);
 module_param(hp_c2502, int, 0);
 
-static int irq[] = { 0, 0, 0, 0, 0, 0, 0, 0 };
+static int irq[] = { IRQ_AUTO, IRQ_AUTO, IRQ_AUTO, IRQ_AUTO, IRQ_AUTO, 
IRQ_AUTO, IRQ_AUTO, IRQ_AUTO };
 module_param_array(irq, int, NULL, 0);
-MODULE_PARM_DESC(irq, "IRQ number(s)");
+MODULE_PARM_DESC(irq, "IRQ number(s) (0=disable, 254=auto [default])");
 
 static int base[] = { 0, 0, 0, 0, 0, 0, 0, 0 };
 module_param_array(base, int, NULL, 0);
-- 
Ondrej Zary

--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 6/6] g_NCR5380: Fix release region in error handling

2016-10-31 Thread Ondrej Zary
When a SW-configurable card is specified but not found, the driver
releases wrong region, causing the following message in kernel log:
Trying to free nonexistent resource <-000f>

Fix it by assigning base earlier.

Signed-off-by: Ondrej Zary 
---
 drivers/scsi/g_NCR5380.c |6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/scsi/g_NCR5380.c b/drivers/scsi/g_NCR5380.c
index 6a08d3e..d33e71f 100644
--- a/drivers/scsi/g_NCR5380.c
+++ b/drivers/scsi/g_NCR5380.c
@@ -258,12 +258,12 @@ static int generic_NCR5380_init_one(struct 
scsi_host_template *tpnt,
if (ports[i]) {
/* At this point we have our region reserved */
magic_configure(i, 0, magic); /* no IRQ yet */
-   outb(0xc0, ports[i] + 9);
-   if (inb(ports[i] + 9) != 0x80) {
+   base = ports[i];
+   outb(0xc0, base + 9);
+   if (inb(base + 9) != 0x80) {
ret = -ENODEV;
goto out_release;
}
-   base = ports[i];
port_idx = i;
} else
return -EINVAL;
-- 
Ondrej Zary

--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 2/3] g_NCR5380: Test the IRQ before accepting it

2016-10-31 Thread Ondrej Zary
On Monday 31 October 2016, Finn Thain wrote:
> On Sun, 30 Oct 2016, Ondrej Zary wrote:
> > Trigger an IRQ first with a test IRQ handler to find out if it really
> > works. Disable the IRQ if not.
> >
> > This prevents hang when incorrect IRQ was specified by user.
> >
> > Signed-off-by: Ondrej Zary 
> > ---
> >  drivers/scsi/g_NCR5380.c |   32 ++--
> >  1 file changed, 30 insertions(+), 2 deletions(-)
> >
> > diff --git a/drivers/scsi/g_NCR5380.c b/drivers/scsi/g_NCR5380.c
> > index 3790ed5..261e168 100644
> > --- a/drivers/scsi/g_NCR5380.c
> > +++ b/drivers/scsi/g_NCR5380.c
> > @@ -67,6 +67,14 @@
> >  MODULE_ALIAS("g_NCR5380_mmio");
> >  MODULE_LICENSE("GPL");
> >
> > +static bool irq_working;
> > +
> > +static irqreturn_t test_irq(int irq, void *dev_id)
> > +{
> > +   irq_working = true;
> > +   return IRQ_HANDLED;
> > +}
> > +
> >  /*
> >   * Configure I/O address of 53C400A or DTC436 by writing magic numbers
> >   * to ports 0x779 and 0x379.
> > @@ -275,10 +283,30 @@ static int generic_NCR5380_init_one(struct
> > scsi_host_template *tpnt, /* set IRQ for HP C2502 */
> > if (board == BOARD_HP_C2502)
> > magic_configure(port_idx, instance->irq, magic);
> > -   if (request_irq(instance->irq, generic_NCR5380_intr,
> > -   0, "NCR5380", instance)) {
> > +   /* test if the IRQ is working */
> > +   irq_working = false;
> > +   if (request_irq(instance->irq, test_irq,
> > +   0, "NCR5380-irqtest", NULL)) {
> > printk(KERN_WARNING "scsi%d : IRQ%d not free, 
> > interrupts disabled\n",
> > instance->host_no, instance->irq); instance->irq = NO_IRQ;
> > +   } else {
> > +   NCR5380_trigger_irq(instance);
> > +   NCR5380_read(RESET_PARITY_INTERRUPT_REG);
> > +   free_irq(instance->irq, NULL);
> > +   if (irq_working) {
> > +   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;
> > +   }
> > +   } else {
> > +   printk(KERN_WARNING "scsi%d : IRQ%d not 
> > working, interrupts
> > disabled\n", + instance->host_no, 
> > instance->irq);
> > +   instance->irq = NO_IRQ;
> > +   }
> > }
> > }
>
> If the user omits to specify an irq, you can just default to IRQ_AUTO.
> This might result in NO_IRQ, which gives the same result as this patch.

Looks like a good idea.

> And when the user does specify an IRQ, we should trust them. So this
> compexity doesn't add any value AFAICT. Thanks but no thanks.

This fixes a real problem: specifying wrong IRQ hangs the machine completely. 
It's really easy - if the IRQ is free but configured in BIOS as PCI IRQ (not 
ISA). Everything seems fine except the IRQ will never trigger.

-- 
Ondrej Zary
--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 1/3] NCR5380: Use probe_irq_*() for IRQ probing

2016-10-31 Thread Ondrej Zary
On Monday 31 October 2016, Finn Thain wrote:
> On Sun, 30 Oct 2016, Ondrej Zary wrote:
> > Use standard probe_irq_on() and probe_irq_off() functions instead of own
> > implementation.
>
> Thanks for doing this.
>
> > This prevents warning messages like this in the kernel log:
> > genirq: Flags mismatch irq 1.  (NCR-probe) vs. 0080 (i8042)
> >
> > Move the IRQ trigger code to a separate function so it can be used for
> > other purposes (testing if the IRQ works).
> >
> > Also add missing IRQ reset after probe.
> >
> > Signed-off-by: Ondrej Zary 
> > ---
> >  drivers/scsi/NCR5380.c   |   72
> > +- drivers/scsi/NCR5380.h   |
> >3 +-
> >  drivers/scsi/g_NCR5380.c |2 +-
> >  3 files changed, 29 insertions(+), 48 deletions(-)
> >
> > diff --git a/drivers/scsi/NCR5380.c b/drivers/scsi/NCR5380.c
> > index d849ffa..01c0027 100644
> > --- a/drivers/scsi/NCR5380.c
> > +++ b/drivers/scsi/NCR5380.c
> > @@ -351,50 +351,13 @@ static void NCR5380_print_phase(struct Scsi_Host
> > *instance) }
> >  #endif
> >
> > -
> > -static int probe_irq;
> > -
> > -/**
> > - * 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.
> > - */
> > -
> > -static irqreturn_t probe_intr(int irq, void *dev_id)
> > -{
> > -   probe_irq = irq;
> > -   return IRQ_HANDLED;
> > -}
> > -
> > -/**
> > - * 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.
> > - */
> > -
> > -static int __maybe_unused NCR5380_probe_irq(struct Scsi_Host *instance,
> > -   int possible)
> > +static void NCR5380_trigger_irq(struct Scsi_Host *instance)
> >  {
> > struct NCR5380_hostdata *hostdata = shost_priv(instance);
> > -   unsigned long timeout;
> > -   int trying_irqs, i, mask;
> > -
> > -   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)) -  trying_irqs |= mask;
> > -
> > -   timeout = jiffies + msecs_to_jiffies(250);
> > -   probe_irq = NO_IRQ;
> > +   unsigned long timeout = jiffies + msecs_to_jiffies(2500);
> >
> > /*
> > -* A interrupt is triggered whenever BSY = false, SEL = true
> > +* An interrupt is triggered whenever BSY = false, SEL = true
> >  * and a bit set in the SELECT_ENABLE_REG is asserted on the
> >  * SCSI bus.
> >  *
> > @@ -402,23 +365,40 @@ static int __maybe_unused NCR5380_probe_irq(struct
> > Scsi_Host *instance, * (I/O, C/D, and MSG) match those in the TCR, so we
> > must reset that * to zero.
> >  */
> > -
> > NCR5380_write(TARGET_COMMAND_REG, 0);
> > NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
> > NCR5380_write(OUTPUT_DATA_REG, hostdata->id_mask);
> > NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_DATA |
> > ICR_ASSERT_SEL);
> >
> > -   while (probe_irq == NO_IRQ && time_before(jiffies, timeout))
> > +   while (!(NCR5380_read(BUS_AND_STATUS_REG) & BASR_IRQ) &&
> > +  time_before(jiffies, timeout))
> > schedule_timeout_uninterruptible(1);
>
> You don't need a 2.5 second timeout here. To raise the interrupt the chip
> should not need more than a bus settle delay (400ns). Calling msleep(1)
> should be plenty.

Yes, 2.5s is a mistake (leftover from testing), sorry.

> Better still, please drop the loop, the delay and the BASR_IRQ test here,
> and if need be, put the delay in the caller. This routine discards the
> result of that sequence anyway.

Will if work if the following lines are executed before the delay?

>
> > NCR5380_write(SELECT_ENABLE_REG, 0);
> > NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
> > +}
> >
> > -   for (i = 1, mask = 2; i < 16; ++i, mask <<= 1)
> > -   if (trying_irqs & mask)
> > -   free_irq(i, NULL);
> > +/**
> > + * NCR538

Re: [PATCH 3/3] NCR5380: Check for chip presence in NCR5380_init()

2016-10-31 Thread Ondrej Zary
On Monday 31 October 2016, Finn Thain wrote:
> On Sun, 30 Oct 2016, Ondrej Zary wrote:
> > Read back MODE_REG after writing it in NCR5380_init() to check if the
> > chip is really there.
> >
> > This prevents hang when incorrect I/O address was specified by user.
> >
> > Signed-off-by: Ondrej Zary 
> > ---
> >  drivers/scsi/NCR5380.c |5 +
> >  1 file changed, 5 insertions(+)
> >
> > diff --git a/drivers/scsi/NCR5380.c b/drivers/scsi/NCR5380.c
> > index 01c0027..ce3156d 100644
> > --- a/drivers/scsi/NCR5380.c
> > +++ b/drivers/scsi/NCR5380.c
> > @@ -495,6 +495,11 @@ static int NCR5380_init(struct Scsi_Host *instance,
> > int flags)
> >
> > NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
> > NCR5380_write(MODE_REG, MR_BASE);
> > +   /* check if the chip is really there */
> > +   if (NCR5380_read(MODE_REG) != MR_BASE) {
> > +   NCR5380_exit(instance);
> > +   return -ENODEV;
> > +   }
>
> This doesn't belong in the core driver. Only the 5380 ISA drivers have
> configurable base addresses.
>
> Also, MR_BASE == 0, so that test is likely to be ineffectual anyway. This
> patch doesn't really add any value AFAICT.

This fixes the most common problem: no device present at the specified I/O 
address, all reads result in 0xff.

-- 
Ondrej Zary
--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 3/3] NCR5380: Check for chip presence in NCR5380_init()

2016-10-30 Thread Ondrej Zary
Read back MODE_REG after writing it in NCR5380_init() to check if the
chip is really there.

This prevents hang when incorrect I/O address was specified by user.

Signed-off-by: Ondrej Zary 
---
 drivers/scsi/NCR5380.c |5 +
 1 file changed, 5 insertions(+)

diff --git a/drivers/scsi/NCR5380.c b/drivers/scsi/NCR5380.c
index 01c0027..ce3156d 100644
--- a/drivers/scsi/NCR5380.c
+++ b/drivers/scsi/NCR5380.c
@@ -495,6 +495,11 @@ static int NCR5380_init(struct Scsi_Host *instance, int 
flags)
 
NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
NCR5380_write(MODE_REG, MR_BASE);
+   /* check if the chip is really there */
+   if (NCR5380_read(MODE_REG) != MR_BASE) {
+   NCR5380_exit(instance);
+   return -ENODEV;
+   }
NCR5380_write(TARGET_COMMAND_REG, 0);
NCR5380_write(SELECT_ENABLE_REG, 0);
 
-- 
Ondrej Zary

--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 2/3] g_NCR5380: Test the IRQ before accepting it

2016-10-30 Thread Ondrej Zary
Trigger an IRQ first with a test IRQ handler to find out if it really
works. Disable the IRQ if not.

This prevents hang when incorrect IRQ was specified by user.

Signed-off-by: Ondrej Zary 
---
 drivers/scsi/g_NCR5380.c |   32 ++--
 1 file changed, 30 insertions(+), 2 deletions(-)

diff --git a/drivers/scsi/g_NCR5380.c b/drivers/scsi/g_NCR5380.c
index 3790ed5..261e168 100644
--- a/drivers/scsi/g_NCR5380.c
+++ b/drivers/scsi/g_NCR5380.c
@@ -67,6 +67,14 @@
 MODULE_ALIAS("g_NCR5380_mmio");
 MODULE_LICENSE("GPL");
 
+static bool irq_working;
+
+static irqreturn_t test_irq(int irq, void *dev_id)
+{
+   irq_working = true;
+   return IRQ_HANDLED;
+}
+
 /*
  * Configure I/O address of 53C400A or DTC436 by writing magic numbers
  * to ports 0x779 and 0x379.
@@ -275,10 +283,30 @@ static int generic_NCR5380_init_one(struct 
scsi_host_template *tpnt,
/* set IRQ for HP C2502 */
if (board == BOARD_HP_C2502)
magic_configure(port_idx, instance->irq, magic);
-   if (request_irq(instance->irq, generic_NCR5380_intr,
-   0, "NCR5380", instance)) {
+   /* test if the IRQ is working */
+   irq_working = false;
+   if (request_irq(instance->irq, test_irq,
+   0, "NCR5380-irqtest", NULL)) {
printk(KERN_WARNING "scsi%d : IRQ%d not free, 
interrupts disabled\n", instance->host_no, instance->irq);
instance->irq = NO_IRQ;
+   } else {
+   NCR5380_trigger_irq(instance);
+   NCR5380_read(RESET_PARITY_INTERRUPT_REG);
+   free_irq(instance->irq, NULL);
+   if (irq_working) {
+   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;
+   }
+   } else {
+   printk(KERN_WARNING "scsi%d : IRQ%d not 
working, interrupts disabled\n",
+  instance->host_no, instance->irq);
+   instance->irq = NO_IRQ;
+   }
}
}
 
-- 
Ondrej Zary

--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 1/3] NCR5380: Use probe_irq_*() for IRQ probing

2016-10-30 Thread Ondrej Zary
Use standard probe_irq_on() and probe_irq_off() functions instead of own
implementation.
This prevents warning messages like this in the kernel log:
genirq: Flags mismatch irq 1.  (NCR-probe) vs. 0080 (i8042)

Move the IRQ trigger code to a separate function so it can be used for
other purposes (testing if the IRQ works).

Also add missing IRQ reset after probe.

Signed-off-by: Ondrej Zary 
---
 drivers/scsi/NCR5380.c   |   72 +-
 drivers/scsi/NCR5380.h   |3 +-
 drivers/scsi/g_NCR5380.c |2 +-
 3 files changed, 29 insertions(+), 48 deletions(-)

diff --git a/drivers/scsi/NCR5380.c b/drivers/scsi/NCR5380.c
index d849ffa..01c0027 100644
--- a/drivers/scsi/NCR5380.c
+++ b/drivers/scsi/NCR5380.c
@@ -351,50 +351,13 @@ static void NCR5380_print_phase(struct Scsi_Host 
*instance)
 }
 #endif
 
-
-static int probe_irq;
-
-/**
- * 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.
- */
-
-static irqreturn_t probe_intr(int irq, void *dev_id)
-{
-   probe_irq = irq;
-   return IRQ_HANDLED;
-}
-
-/**
- * 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.
- */
-
-static int __maybe_unused NCR5380_probe_irq(struct Scsi_Host *instance,
-   int possible)
+static void NCR5380_trigger_irq(struct Scsi_Host *instance)
 {
struct NCR5380_hostdata *hostdata = shost_priv(instance);
-   unsigned long timeout;
-   int trying_irqs, i, mask;
-
-   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))
-   trying_irqs |= mask;
-
-   timeout = jiffies + msecs_to_jiffies(250);
-   probe_irq = NO_IRQ;
+   unsigned long timeout = jiffies + msecs_to_jiffies(2500);
 
/*
-* A interrupt is triggered whenever BSY = false, SEL = true
+* An interrupt is triggered whenever BSY = false, SEL = true
 * and a bit set in the SELECT_ENABLE_REG is asserted on the
 * SCSI bus.
 *
@@ -402,23 +365,40 @@ static int __maybe_unused NCR5380_probe_irq(struct 
Scsi_Host *instance,
 * (I/O, C/D, and MSG) match those in the TCR, so we must reset that
 * to zero.
 */
-
NCR5380_write(TARGET_COMMAND_REG, 0);
NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
NCR5380_write(OUTPUT_DATA_REG, hostdata->id_mask);
NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_DATA | 
ICR_ASSERT_SEL);
 
-   while (probe_irq == NO_IRQ && time_before(jiffies, timeout))
+   while (!(NCR5380_read(BUS_AND_STATUS_REG) & BASR_IRQ) &&
+  time_before(jiffies, timeout))
schedule_timeout_uninterruptible(1);
 
NCR5380_write(SELECT_ENABLE_REG, 0);
NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
+}
 
-   for (i = 1, mask = 2; i < 16; ++i, mask <<= 1)
-   if (trying_irqs & mask)
-   free_irq(i, NULL);
+/**
+ * NCR5380_probe_irq   -   find the IRQ of an NCR5380
+ * @instance: NCR5380 controller
+ *
+ * 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 NCR5380_probe_irq(struct Scsi_Host *instance)
+{
+   struct NCR5380_hostdata *hostdata = shost_priv(instance);
+   int irqs, irq;
+
+   irqs = probe_irq_on();
+   NCR5380_trigger_irq(instance);
+   irq = probe_irq_off(irqs);
+   NCR5380_read(RESET_PARITY_INTERRUPT_REG);
+   if (irq < 0)
+   irq = 0;
 
-   return probe_irq;
+   return irq;
 }
 
 /**
diff --git a/drivers/scsi/NCR5380.h b/drivers/scsi/NCR5380.h
index 3c6ce54..b2fca52 100644
--- a/drivers/scsi/NCR5380.h
+++ b/drivers/scsi/NCR5380.h
@@ -290,7 +290,8 @@ static inline struct scsi_cmnd *NCR5380_to_scmd(struct 
NCR5380_cmd *ncmd_ptr)
 #define NCR5380_dprint_phase(flg, arg) do {} while (0)
 #endif
 
-static int NCR5380_probe_irq(struct Scsi_Host *instance, int possible);
+static void NCR5380_trigger_irq(struct Scsi_Host *instance);
+static int NCR5380_probe_irq(struct Scsi_Host *instance);
 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);
diff --git a/drivers/scsi/g_NCR5380.c b/drivers/scsi/g_NCR5380.c
index 7299ad9..3790ed5 100644
--- a/drivers/scsi/g_NCR5380.c
+++ b/drivers/scsi/g_NCR5380.c
@@ -265,7 +

[PATCH 1/2] NCR5380: Use probe_irq_*() for IRQ probing

2016-10-30 Thread Ondrej Zary
Use standard probe_irq_on() and probe_irq_off() functions instead of own
implementation.
This prevents warning messages like this in the kernel log:
genirq: Flags mismatch irq 1.  (NCR-probe) vs. 0080 (i8042)

Move the IRQ trigger code to a separate function so it can be used for
other purposes (testing if the IRQ works).

Also add missing IRQ reset after probe.

Signed-off-by: Ondrej Zary 
---
 drivers/scsi/NCR5380.c   |   72 +-
 drivers/scsi/NCR5380.h   |3 +-
 drivers/scsi/g_NCR5380.c |2 +-
 3 files changed, 29 insertions(+), 48 deletions(-)

diff --git a/drivers/scsi/NCR5380.c b/drivers/scsi/NCR5380.c
index d849ffa..01c0027 100644
--- a/drivers/scsi/NCR5380.c
+++ b/drivers/scsi/NCR5380.c
@@ -351,50 +351,13 @@ static void NCR5380_print_phase(struct Scsi_Host 
*instance)
 }
 #endif
 
-
-static int probe_irq;
-
-/**
- * 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.
- */
-
-static irqreturn_t probe_intr(int irq, void *dev_id)
-{
-   probe_irq = irq;
-   return IRQ_HANDLED;
-}
-
-/**
- * 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.
- */
-
-static int __maybe_unused NCR5380_probe_irq(struct Scsi_Host *instance,
-   int possible)
+static void NCR5380_trigger_irq(struct Scsi_Host *instance)
 {
struct NCR5380_hostdata *hostdata = shost_priv(instance);
-   unsigned long timeout;
-   int trying_irqs, i, mask;
-
-   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))
-   trying_irqs |= mask;
-
-   timeout = jiffies + msecs_to_jiffies(250);
-   probe_irq = NO_IRQ;
+   unsigned long timeout = jiffies + msecs_to_jiffies(2500);
 
/*
-* A interrupt is triggered whenever BSY = false, SEL = true
+* An interrupt is triggered whenever BSY = false, SEL = true
 * and a bit set in the SELECT_ENABLE_REG is asserted on the
 * SCSI bus.
 *
@@ -402,23 +365,40 @@ static int __maybe_unused NCR5380_probe_irq(struct 
Scsi_Host *instance,
 * (I/O, C/D, and MSG) match those in the TCR, so we must reset that
 * to zero.
 */
-
NCR5380_write(TARGET_COMMAND_REG, 0);
NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
NCR5380_write(OUTPUT_DATA_REG, hostdata->id_mask);
NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_DATA | 
ICR_ASSERT_SEL);
 
-   while (probe_irq == NO_IRQ && time_before(jiffies, timeout))
+   while (!(NCR5380_read(BUS_AND_STATUS_REG) & BASR_IRQ) &&
+  time_before(jiffies, timeout))
schedule_timeout_uninterruptible(1);
 
NCR5380_write(SELECT_ENABLE_REG, 0);
NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
+}
 
-   for (i = 1, mask = 2; i < 16; ++i, mask <<= 1)
-   if (trying_irqs & mask)
-   free_irq(i, NULL);
+/**
+ * NCR5380_probe_irq   -   find the IRQ of an NCR5380
+ * @instance: NCR5380 controller
+ *
+ * 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 NCR5380_probe_irq(struct Scsi_Host *instance)
+{
+   struct NCR5380_hostdata *hostdata = shost_priv(instance);
+   int irqs, irq;
+
+   irqs = probe_irq_on();
+   NCR5380_trigger_irq(instance);
+   irq = probe_irq_off(irqs);
+   NCR5380_read(RESET_PARITY_INTERRUPT_REG);
+   if (irq < 0)
+   irq = 0;
 
-   return probe_irq;
+   return irq;
 }
 
 /**
diff --git a/drivers/scsi/NCR5380.h b/drivers/scsi/NCR5380.h
index 3c6ce54..b2fca52 100644
--- a/drivers/scsi/NCR5380.h
+++ b/drivers/scsi/NCR5380.h
@@ -290,7 +290,8 @@ static inline struct scsi_cmnd *NCR5380_to_scmd(struct 
NCR5380_cmd *ncmd_ptr)
 #define NCR5380_dprint_phase(flg, arg) do {} while (0)
 #endif
 
-static int NCR5380_probe_irq(struct Scsi_Host *instance, int possible);
+static void NCR5380_trigger_irq(struct Scsi_Host *instance);
+static int NCR5380_probe_irq(struct Scsi_Host *instance);
 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);
diff --git a/drivers/scsi/g_NCR5380.c b/drivers/scsi/g_NCR5380.c
index 7299ad9..3790ed5 100644
--- a/drivers/scsi/g_NCR5380.c
+++ b/drivers/scsi/g_NCR5380.c
@@ -265,7 +

[PATCH 2/2] g_NCR5380: Test the IRQ before accepting it

2016-10-30 Thread Ondrej Zary
Trigger an IRQ first with a test IRQ handler to find out if it really
works. Disable the IRQ if not.
This prevents hang when incorrect IRQ was specified by user.

Signed-off-by: Ondrej Zary 
---
 drivers/scsi/g_NCR5380.c |   31 +--
 1 file changed, 29 insertions(+), 2 deletions(-)

diff --git a/drivers/scsi/g_NCR5380.c b/drivers/scsi/g_NCR5380.c
index 3790ed5..f0c5b10 100644
--- a/drivers/scsi/g_NCR5380.c
+++ b/drivers/scsi/g_NCR5380.c
@@ -67,6 +67,14 @@
 MODULE_ALIAS("g_NCR5380_mmio");
 MODULE_LICENSE("GPL");
 
+static bool irq_working;
+
+static irqreturn_t test_irq(int irq, void *dev_id)
+{
+   irq_working = true;
+   return IRQ_HANDLED;
+}
+
 /*
  * Configure I/O address of 53C400A or DTC436 by writing magic numbers
  * to ports 0x779 and 0x379.
@@ -275,10 +283,29 @@ static int generic_NCR5380_init_one(struct 
scsi_host_template *tpnt,
/* set IRQ for HP C2502 */
if (board == BOARD_HP_C2502)
magic_configure(port_idx, instance->irq, magic);
-   if (request_irq(instance->irq, generic_NCR5380_intr,
-   0, "NCR5380", instance)) {
+   /* test if the IRQ is working */
+   irq_working = false;
+   if (request_irq(instance->irq, test_irq,
+   0, "NCR5380-irqtest", NULL)) {
printk(KERN_WARNING "scsi%d : IRQ%d not free, 
interrupts disabled\n", instance->host_no, instance->irq);
instance->irq = NO_IRQ;
+   } else {
+   NCR5380_trigger_irq(instance);
+   free_irq(instance->irq, NULL);
+   if (irq_working) {
+   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;
+   }
+   } else {
+   printk(KERN_WARNING "scsi%d : IRQ%d not 
working, interrupts disabled\n",
+  instance->host_no, instance->irq);
+   instance->irq = NO_IRQ;
+   }
}
}
 
-- 
Ondrej Zary

--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] scsi: NCR5380: no longer mark irq probing as __init

2016-10-11 Thread Ondrej Zary
On Tuesday 11 October 2016 11:39:57 Finn Thain wrote:
> Acked-by: Finn Thain 
>
> Thanks.
>
> On Tue, 11 Oct 2016, Arnd Bergmann wrote:
> > The g_NCR5380 has been converted to more regular probing, which
> > means its probe function can now be invoked after the __init section
> > is discarded, as pointed out by this kbuild warning:
> >
> > WARNING: drivers/scsi/built-in.o(.text+0x3a105): Section mismatch in
> > reference from the function generic_NCR5380_isa_match() to the function
> > .init.text:probe_intr() WARNING: drivers/scsi/built-in.o(.text+0x3a145):
> > Section mismatch in reference from the function
> > generic_NCR5380_isa_match() to the variable .init.data:probe_irq
> >
> > To make sure this works correctly in all cases, let's remove
> > the __init and __initdata annotations.
> >
> > Fixes: a8cfbcaec0c1 ("scsi: g_NCR5380: Stop using scsi_module.c")
> > Signed-off-by: Arnd Bergmann 
> > ---
> >  drivers/scsi/NCR5380.c | 6 +++---
> >  1 file changed, 3 insertions(+), 3 deletions(-)
> >
> > diff --git a/drivers/scsi/NCR5380.c b/drivers/scsi/NCR5380.c
> > index 7053de5bd468..61f34aca2fa0 100644
> > --- a/drivers/scsi/NCR5380.c
> > +++ b/drivers/scsi/NCR5380.c
> > @@ -353,7 +353,7 @@ static void NCR5380_print_phase(struct Scsi_Host
> > *instance) #endif
> >
> >
> > -static int probe_irq __initdata;
> > +static int probe_irq;
> >
> >  /**
> >   * probe_intr  -   helper for IRQ autoprobe
> > @@ -365,7 +365,7 @@ static int probe_irq __initdata;
> >   * used by the IRQ probe code.
> >   */
> >
> > -static irqreturn_t __init probe_intr(int irq, void *dev_id)
> > +static irqreturn_t probe_intr(int irq, void *dev_id)
> >  {
> > probe_irq = irq;
> > return IRQ_HANDLED;
> > @@ -380,7 +380,7 @@ static irqreturn_t __init probe_intr(int irq, void
> > *dev_id) * and then looking to see what interrupt actually turned up.
> >   */
> >
> > -static int __init __maybe_unused NCR5380_probe_irq(struct Scsi_Host
> > *instance, +static int __maybe_unused NCR5380_probe_irq(struct Scsi_Host
> > *instance, int possible)
> >  {
> > struct NCR5380_hostdata *hostdata = shost_priv(instance);

I've tested IRQ probing on my IRQ7-hardwired ISA card without any success some 
time ago. No IRQ was detected because it wasn't even generated (no increment 
in /proc/interruptts). It also produced some warnings in dmesg about 
conflicting interrupt flags. Can't the IRQ probing be simply deleted?

-- 
Ondrej Zary
--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v2 00/12] Fixes, cleanup and g_NCR5380_mmio/g_NCR5380 merger

2016-10-07 Thread Ondrej Zary
On Friday 07 October 2016 01:41:06 Finn Thain wrote:
> This patch series has fixes for compatibility, reliability and
> performance issues and some cleanup. It also includes a new version
> of Ondrej Zary's patch that merges g_NCR5380_mmio into g_NCR5380.
>
> I've tested this patch series on a Powerbook 180. If someone would
> test some of the other platforms that would be very helpful. All
> drivers were compile-tested.
>
> Changes since v1:
> - rebased on 4.9/scsi-queue
> - added reviewed-by tags
> - tweaked the order of struct members in patch 7/12
>
>
> Finn Thain (12):
>   scsi/g_NCR5380: Merge g_NCR5380 and g_NCR5380_mmio drivers
>   scsi/cumana_1: Remove unused cumanascsi_setup() function
>   scsi/atari_scsi: Make device register accessors re-enterant
>   scsi/ncr5380: Simplify register polling limit
>   scsi/ncr5380: Increase register polling limit
>   scsi/ncr5380: Improve hostdata struct member alignment and
> cache-ability
>   scsi/ncr5380: Store IO ports and addresses in host private data
>   scsi/ncr5380: Use correct types for device register accessors
>   scsi/ncr5380: Pass hostdata pointer to register polling routines
>   scsi/ncr5380: Expedite register polling
>   scsi/ncr5380: Use correct types for DMA routines
>   scsi/ncr5380: Suppress unhelpful "interrupt without IRQ bit" message

Tested on HP C2502 (53C400A chip), Canon FG2-5202 (53C400 chip) and DTC-3181L
(DTCT-436P chip) ISA cards - everything works fine!

Thanks.

Tested-by: Ondrej Zary 


-- 
Ondrej Zary
--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 00/12] Fixes, cleanup and g_NCR5380_mmio/g_NCR5380 merger

2016-10-05 Thread Ondrej Zary
On Tuesday 04 October 2016 07:40:50 Finn Thain wrote:
> This patch series has fixes for compatibility, reliability and
> performance issues and some cleanup. It also includes a new version
> of Ondrej Zary's patch that merges g_NCR5380_mmio into g_NCR5380.
>
> I've tested this patch series on a Powerbook 180. If someone would
> test some of the other platforms that would be very helpful. All
> drivers were compile-tested.
>
> (Apologies for any duplicate messages.)

The patches won't apply against:
4.9/scsi-queue
Linus' master with my patches applied

What tree should I try?

> Finn Thain (12):
>   scsi/g_NCR5380: Merge g_NCR5380 and g_NCR5380_mmio drivers
>   scsi/cumana_1: Remove unused cumanascsi_setup() function
>   scsi/atari_scsi: Make device register accessors re-enterant
>   scsi/ncr5380: Simplify register polling limit
>   scsi/ncr5380: Increase register polling limit
>   scsi/ncr5380: Improve hostdata struct member alignment and
> cache-ability
>   scsi/ncr5380: Store IO ports and addresses in host private data
>   scsi/ncr5380: Use correct types for device register accessors
>   scsi/ncr5380: Pass hostdata pointer to register polling routines
>   scsi/ncr5380: Expedite register polling
>   scsi/ncr5380: Use correct types for DMA routines
>   scsi/ncr5380: Suppress unhelpful "interrupt without IRQ bit" message
>
>  MAINTAINERS   |   1 -
>  drivers/scsi/Kconfig  |  32 +
>  drivers/scsi/Makefile |   1 -
>  drivers/scsi/NCR5380.c| 137 +++-
>  drivers/scsi/NCR5380.h|  87 +
>  drivers/scsi/arm/cumana_1.c   |  98 +++---
>  drivers/scsi/arm/oak.c|  34 +++--
>  drivers/scsi/atari_scsi.c |  77 ++-
>  drivers/scsi/dmx3191d.c   |  20 +--
>  drivers/scsi/g_NCR5380.c  | 290
> -- drivers/scsi/g_NCR5380.h  | 
> 32 +
>  drivers/scsi/g_NCR5380_mmio.c |  10 --
>  drivers/scsi/mac_scsi.c   |  83 +---
>  drivers/scsi/sun3_scsi.c  |  80 ++--
>  14 files changed, 495 insertions(+), 487 deletions(-)
>  delete mode 100644 drivers/scsi/g_NCR5380_mmio.c


-- 
Ondrej Zary
--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v2 0/3] g_NCR5380: Modernization

2016-09-27 Thread Ondrej Zary

This small patch series removes deprecated code from g_NCR5380 driver
and converts it from scsi_module.c to scsi_add_host().

Tested with:
HP C2502 (53C400A chip)
Canon FG2-5202 (53C400 chip, memory-mapped)
DTC-3181L (DTCT-436P chip, PnP)

---
Changes in v2: 
 - updated Documentation/scsi/g_NCR5380.txt
 - kept old-style module parameters for compatibility
 - added missing NCR5380_exit() call
 - fixed error propagation from init
 - simplified driver registration

-- 
Ondrej Zary
--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 3/3] g_NCR5380: Stop using scsi_module.c

2016-09-27 Thread Ondrej Zary
Convert g_NCR5380 to use scsi_add_host instead of scsi_module.c
Use pnp_driver and isa_driver to manage cards.

In order to support multiple cards, new module parameter format is
introduced. The old parameters are kept for compatibility.

Signed-off-by: Ondrej Zary 
---
 Documentation/scsi/g_NCR5380.txt |   24 ++-
 drivers/scsi/g_NCR5380.c |  335 ++
 drivers/scsi/g_NCR5380.h |8 -
 3 files changed, 215 insertions(+), 152 deletions(-)

diff --git a/Documentation/scsi/g_NCR5380.txt b/Documentation/scsi/g_NCR5380.txt
index 843cbae..e2c1879 100644
--- a/Documentation/scsi/g_NCR5380.txt
+++ b/Documentation/scsi/g_NCR5380.txt
@@ -28,6 +28,16 @@ time. More info to come in the future.
 This driver works as a module.
 When included as a module, parameters can be passed on the insmod/modprobe
 command line:
+  irq=xx[,...] the interrupt(s)
+  base=xx[,...]the port or base address(es) (for port or memory 
mapped, resp.)
+  card=xx[,...]card type(s):
+   0 = NCR5380,
+   1 = NCR53C400,
+   2 = NCR53C400A,
+   3 = Domex Technology Corp 3181E (DTC3181E)
+   4 = Hewlett Packard C2502
+
+These old-style parameters can support only one card:
   ncr_irq=xx   the interrupt
   ncr_addr=xx  the port or base address (for port or memory
mapped, resp.)
@@ -36,11 +46,19 @@ command line:
   ncr_53c400a=1 to set up for a NCR53C400A board
   dtc_3181e=1  to set up for a Domex Technology Corp 3181E board
   hp_c2502=1   to set up for a Hewlett Packard C2502 board
+
 e.g.
-modprobe g_NCR5380 ncr_irq=5 ncr_addr=0x350 ncr_5380=1
+OLD: modprobe g_NCR5380 ncr_irq=5 ncr_addr=0x350 ncr_5380=1
+NEW: modprobe g_NCR5380 irq=5 base=0x350 card=0
   for a port mapped NCR5380 board or
-modprobe g_NCR5380 ncr_irq=255 ncr_addr=0xc8000 ncr_53c400=1
-  for a memory mapped NCR53C400 board with interrupts disabled.
+
+OLD: modprobe g_NCR5380 ncr_irq=255 ncr_addr=0xc8000 ncr_53c400=1
+NEW: modprobe g_NCR5380 irq=255 base=0xc8000 card=1
+  for a memory mapped NCR53C400 board with interrupts disabled or
+
+NEW: modprobe g_NCR5380 irq=0,7 base=0x240,0x300 card=3,4
+  for two cards: DTC3181 (in non-PnP mode) at 0x240 with no IRQ
+ and HP C2502 at 0x300 with IRQ 7
 
 (255 should be specified for no or DMA interrupt, 254 to autoprobe for an 
  IRQ line if overridden on the command line.)
diff --git a/drivers/scsi/g_NCR5380.c b/drivers/scsi/g_NCR5380.c
index 5162de6..cbf0103 100644
--- a/drivers/scsi/g_NCR5380.c
+++ b/drivers/scsi/g_NCR5380.c
@@ -30,24 +30,41 @@
 #include "NCR5380.h"
 #include 
 #include 
-#include 
+#include 
+#include 
 #include 
 
+#define MAX_CARDS 8
+
+/* old-style parameters for compatibility */
 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 int hp_c2502;
+module_param(ncr_irq, int, 0);
+module_param(ncr_addr, int, 0);
+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);
+
+static int irq[] = { 0, 0, 0, 0, 0, 0, 0, 0 };
+module_param_array(irq, int, NULL, 0);
+MODULE_PARM_DESC(irq, "IRQ number(s)");
 
-static struct card {
-   NCR5380_map_type NCR5380_map_name;
-   int irq;
-   int dma;
-   int board;  /* Use NCR53c400, Ricoh, etc. extensions ? */
-} card;
+static int base[] = { 0, 0, 0, 0, 0, 0, 0, 0 };
+module_param_array(base, int, NULL, 0);
+MODULE_PARM_DESC(base, "base address(es)");
+
+static int card[] = { -1, -1, -1, -1, -1, -1, -1, -1 };
+module_param_array(card, int, NULL, 0);
+MODULE_PARM_DESC(card, "card type (0=NCR5380, 1=NCR53C400, 2=NCR53C400A, 
3=DTC3181E, 4=HP C2502)");
+
+MODULE_LICENSE("GPL");
 
 #ifndef SCSI_G_NCR5380_MEM
 /*
@@ -73,17 +90,8 @@ static void magic_configure(int idx, u8 irq, u8 magic[])
 }
 #endif
 
-/**
- * generic_NCR5380_detect  -   look for NCR5380 controllers
- * @tpnt: the scsi template
- *
- * Scan for the present of NCR5380, NCR53C400, NCR53C400A, DTC3181E
- * and DTC436(ISAPnP) controllers.
- *
- * Locks: none
- */
-
-static int __init generic_NCR5380_detect(struct scsi_host_template *tpnt)
+static int generic_NCR5380_init_one(struct scsi_host_template *tpnt,
+   struct device *pdev, int base, int irq, int board)
 {
unsigned int *ports;
u8 *magic = NULL;
@@ -92,80 +100,29 @@ static int __init generic_NCR5380_detect(struct 
scsi_host_template *tpnt)
int port_idx = -1;
unsigned long region_size;
 #endif
-   static unsigned int __initdata ncr_53c400a_ports[] = {
+   static unsigned int ncr_53c400a_ports[] = {
0x280, 0x290, 0x300, 0x310, 0x330, 0x340, 0x348, 0x350, 0
};
-   static unsigned int __initdata dtc_3181e_ports

[PATCH 1/3] g_NCR5380: Remove deprecated __setup

2016-09-27 Thread Ondrej Zary
Remove deprecated __setup for parsing command line parameters.
g_NCR5380.* parameters could be used instead.

This might break existing setups with g_NCR5380 built-in (if there are
any). But it has to go in order to remove the overrides[] array.

Signed-off-by: Ondrej Zary 
---
 Documentation/scsi/g_NCR5380.txt |   10 ---
 drivers/scsi/g_NCR5380.c |  135 --
 2 files changed, 145 deletions(-)

diff --git a/Documentation/scsi/g_NCR5380.txt b/Documentation/scsi/g_NCR5380.txt
index fd88015..843cbae 100644
--- a/Documentation/scsi/g_NCR5380.txt
+++ b/Documentation/scsi/g_NCR5380.txt
@@ -21,16 +21,6 @@ NCR53c400 card, the Trantor T130B in its default 
configuration:
 The NCR53c400 does not support DMA but it does have Pseudo-DMA which is
 supported by the driver.
 
-If the default configuration does not work for you, you can use the kernel
-command lines (eg using the lilo append command):
-   ncr5380=addr,irq
-   ncr53c400=addr,irq
-   ncr53c400a=addr,irq
-   dtc3181e=addr,irq
-
-The driver does not probe for any addresses or ports other than those in
-the OVERRIDE or given to the kernel as above.
-
 This driver provides some information on what it has detected in
 /proc/scsi/g_NCR5380/x where x is the scsi card number as detected at boot
 time. More info to come in the future.
diff --git a/drivers/scsi/g_NCR5380.c b/drivers/scsi/g_NCR5380.c
index 516bd6c..7e50b44e 100644
--- a/drivers/scsi/g_NCR5380.c
+++ b/drivers/scsi/g_NCR5380.c
@@ -56,136 +56,6 @@ static struct override {
 
 #define NO_OVERRIDES ARRAY_SIZE(overrides)
 
-#ifndef MODULE
-
-/**
- * internal_setup  -   handle lilo command string override
- * @board: BOARD_* identifier for the board
- * @str: unused
- * @ints: numeric parameters
- *
- * Do LILO command line initialization of the overrides array. Display
- * errors when needed
- *
- * Locks: none
- */
-
-static void __init internal_setup(int board, char *str, int *ints)
-{
-   static int commandline_current;
-   switch (board) {
-   case BOARD_NCR5380:
-   if (ints[0] != 2 && ints[0] != 3) {
-   printk(KERN_ERR "generic_NCR5380_setup : usage 
ncr5380=" STRVAL(NCR5380_map_name) ",irq,dma\n");
-   return;
-   }
-   break;
-   case BOARD_NCR53C400:
-   if (ints[0] != 2) {
-   printk(KERN_ERR "generic_NCR53C400_setup : usage 
ncr53c400=" STRVAL(NCR5380_map_name) ",irq\n");
-   return;
-   }
-   break;
-   case BOARD_NCR53C400A:
-   if (ints[0] != 2) {
-   printk(KERN_ERR "generic_NCR53C400A_setup : usage 
ncr53c400a=" STRVAL(NCR5380_map_name) ",irq\n");
-   return;
-   }
-   break;
-   case BOARD_DTC3181E:
-   if (ints[0] != 2) {
-   printk("generic_DTC3181E_setup : usage dtc3181e=" 
STRVAL(NCR5380_map_name) ",irq\n");
-   return;
-   }
-   break;
-   }
-
-   if (commandline_current < NO_OVERRIDES) {
-   overrides[commandline_current].NCR5380_map_name = 
(NCR5380_map_type) ints[1];
-   overrides[commandline_current].irq = ints[2];
-   if (ints[0] == 3)
-   overrides[commandline_current].dma = ints[3];
-   else
-   overrides[commandline_current].dma = DMA_NONE;
-   overrides[commandline_current].board = board;
-   ++commandline_current;
-   }
-}
-
-
-/**
- * do_NCR53C80_setup   -   set up entry point
- * @str: unused
- *
- * Setup function invoked at boot to parse the ncr5380= command
- * line.
- */
-
-static int __init do_NCR5380_setup(char *str)
-{
-   int ints[10];
-
-   get_options(str, ARRAY_SIZE(ints), ints);
-   internal_setup(BOARD_NCR5380, str, ints);
-   return 1;
-}
-
-/**
- * do_NCR53C400_setup  -   set up entry point
- * @str: unused
- * @ints: integer parameters from kernel setup code
- *
- * Setup function invoked at boot to parse the ncr53c400= command
- * line.
- */
-
-static int __init do_NCR53C400_setup(char *str)
-{
-   int ints[10];
-
-   get_options(str, ARRAY_SIZE(ints), ints);
-   internal_setup(BOARD_NCR53C400, str, ints);
-   return 1;
-}
-
-/**
- * do_NCR53C400A_setup -   set up entry point
- * @str: unused
- * @ints: integer parameters from kernel setup code
- *
- * Setup function invoked at boot to parse the ncr53c400a= command
- * line.
- */
-
-static int __init do_NCR53C400A_setup(char *str)
-{
-   int ints[10];
-
-   get_options(str, ARRAY_SIZE(ints), ints);
-   internal_setup(BOARD_NCR53C400A, s

[PATCH 2/3] g_NCR5380: Reduce overrides[] from array to struct

2016-09-27 Thread Ondrej Zary
Remove compile-time card type definition GENERIC_NCR5380_OVERRIDE.
Then remove all code iterating the overrides[] array and reduce it to
struct card.

Signed-off-by: Ondrej Zary 
---
 drivers/scsi/g_NCR5380.c |  351 ++
 1 file changed, 167 insertions(+), 184 deletions(-)

diff --git a/drivers/scsi/g_NCR5380.c b/drivers/scsi/g_NCR5380.c
index 7e50b44e..5162de6 100644
--- a/drivers/scsi/g_NCR5380.c
+++ b/drivers/scsi/g_NCR5380.c
@@ -42,19 +42,12 @@ static int ncr_53c400a;
 static int dtc_3181e;
 static int hp_c2502;
 
-static struct override {
+static struct card {
NCR5380_map_type NCR5380_map_name;
int irq;
int dma;
int board;  /* Use NCR53c400, Ricoh, etc. extensions ? */
-} overrides
-#ifdef GENERIC_NCR5380_OVERRIDE
-[] __initdata = GENERIC_NCR5380_OVERRIDE;
-#else
-[1] __initdata = { { 0,},};
-#endif
-
-#define NO_OVERRIDES ARRAY_SIZE(overrides)
+} card;
 
 #ifndef SCSI_G_NCR5380_MEM
 /*
@@ -85,16 +78,13 @@ static void magic_configure(int idx, u8 irq, u8 magic[])
  * @tpnt: the scsi template
  *
  * Scan for the present of NCR5380, NCR53C400, NCR53C400A, DTC3181E
- * and DTC436(ISAPnP) controllers. If overrides have been set we use
- * them.
+ * and DTC436(ISAPnP) controllers.
  *
  * Locks: none
  */
 
 static int __init generic_NCR5380_detect(struct scsi_host_template *tpnt)
 {
-   static int current_override;
-   int count;
unsigned int *ports;
u8 *magic = NULL;
 #ifndef SCSI_G_NCR5380_MEM
@@ -124,28 +114,25 @@ static int __init generic_NCR5380_detect(struct 
scsi_host_template *tpnt)
 #endif
 
if (ncr_irq)
-   overrides[0].irq = ncr_irq;
+   card.irq = ncr_irq;
if (ncr_dma)
-   overrides[0].dma = ncr_dma;
+   card.dma = ncr_dma;
if (ncr_addr)
-   overrides[0].NCR5380_map_name = (NCR5380_map_type) ncr_addr;
+   card.NCR5380_map_name = (NCR5380_map_type) ncr_addr;
if (ncr_5380)
-   overrides[0].board = BOARD_NCR5380;
+   card.board = BOARD_NCR5380;
else if (ncr_53c400)
-   overrides[0].board = BOARD_NCR53C400;
+   card.board = BOARD_NCR53C400;
else if (ncr_53c400a)
-   overrides[0].board = BOARD_NCR53C400A;
+   card.board = BOARD_NCR53C400A;
else if (dtc_3181e)
-   overrides[0].board = BOARD_DTC3181E;
+   card.board = BOARD_DTC3181E;
else if (hp_c2502)
-   overrides[0].board = BOARD_HP_C2502;
+   card.board = BOARD_HP_C2502;
 #ifndef SCSI_G_NCR5380_MEM
-   if (!current_override && isapnp_present()) {
+   if (isapnp_present()) {
struct pnp_dev *dev = NULL;
-   count = 0;
while ((dev = pnp_find_dev(NULL, ISAPNP_VENDOR('D', 'T', 'C'), 
ISAPNP_FUNCTION(0x436e), dev))) {
-   if (count >= NO_OVERRIDES)
-   break;
if (pnp_device_attach(dev) < 0)
continue;
if (pnp_activate_dev(dev) < 0) {
@@ -159,202 +146,198 @@ static int __init generic_NCR5380_detect(struct 
scsi_host_template *tpnt)
continue;
}
if (pnp_irq_valid(dev, 0))
-   overrides[count].irq = pnp_irq(dev, 0);
+   card.irq = pnp_irq(dev, 0);
else
-   overrides[count].irq = NO_IRQ;
+   card.irq = NO_IRQ;
if (pnp_dma_valid(dev, 0))
-   overrides[count].dma = pnp_dma(dev, 0);
+   card.dma = pnp_dma(dev, 0);
else
-   overrides[count].dma = DMA_NONE;
-   overrides[count].NCR5380_map_name = (NCR5380_map_type) 
pnp_port_start(dev, 0);
-   overrides[count].board = BOARD_DTC3181E;
-   count++;
+   card.dma = DMA_NONE;
+   card.NCR5380_map_name = (NCR5380_map_type) 
pnp_port_start(dev, 0);
+   card.board = BOARD_DTC3181E;
+   break;
}
}
 #endif
 
-   for (count = 0; current_override < NO_OVERRIDES; ++current_override) {
-   if (!(overrides[current_override].NCR5380_map_name))
-   continue;
+   if (!(card.NCR5380_map_name))
+   return 0;
 
-   ports = NULL;
-   flags = 0;
-   switch (overrides[current_override].board) {
-   case BOARD_NCR5380:
-   flags = FLAG_NO_PSEUDO_DMA | FLAG_DMA_FIXUP;
- 

Re: [PATCH 3/3] g_NCR5380: Stop using scsi_module.c

2016-09-27 Thread Ondrej Zary
On Monday 26 September 2016, Finn Thain wrote:

[...]

> Instead of this:
> > +   if (scsi_add_host(instance, pdev)) {
> > +   free_irq(irq, instance);
> > +   goto out_unregister;
> > +   }
> > +   scsi_scan_host(instance);
> > +   return instance;
>
> please use the following (note the missing NCR5380_exit() call):
>
> + if (scsi_add_host(instance, pdev))
> + goto out_free_irq;
> + scsi_scan_host(instance);
> + return(instance);
> +
> +out_free_irq:
> + if (instance->irq != NO_IRQ)
> + free_irq(instance->irq, instance);
> + NCR5380_exit(instance);
>
> >  out_unregister:
> > -   scsi_unregister(instance);
> > +   scsi_host_put(instance);
> >  out_release:
> >  #ifndef SCSI_G_NCR5380_MEM
> > -   release_region(card.NCR5380_map_name, region_size);
> > +   release_region(base, region_size);
> >  #else
> > iounmap(iomem);
> > release_mem_region(base, iomem_size);
> >  #endif
> > -   return 0;
> > +   return NULL;
> >  }
> >
> > -/**
> > - * generic_NCR5380_release_resources   -   free resources
> > - * @instance: host adapter to clean up
> > - *
> > - * Free the generic interface resources from this adapter.
> > - *
> > - * Locks: none
> > - */
> > -
> > -static int generic_NCR5380_release_resources(struct Scsi_Host *instance)
> > +static void generic_NCR5380_release_resources(struct Scsi_Host
> > *instance) {
> > +   scsi_remove_host(instance);
> > if (instance->irq != NO_IRQ)
> > free_irq(instance->irq, instance);
> > NCR5380_exit(instance);
> > @@ -364,7 +304,7 @@ static int generic_NCR5380_release_resources(struct
> > Scsi_Host *instance) release_mem_region(instance->base,
> > hostdata->iomem_size);
> > }
> >  #endif
> > -   return 0;
> > +   scsi_host_put(instance);
>
> The sequence of operations here should be the same as the error path
> above.

I put scsi_host_put() call at the end because the release_mem_region code (in 
the MMIO case) dereferences the hostdata pointer. I don't think it's safe to 
do after scsi_host_put().

[...]

> > +static int pnp_registered;
> > +#endif /* !defined(SCSI_G_NCR5380_MEM) && defined(CONFIG_PNP) */
> > +
> > +static int __init generic_NCR5380_init(void)
> > +{
> > +   int ret = 0;
> > +
> > +#if !defined(SCSI_G_NCR5380_MEM) && defined(CONFIG_PNP)
> > +   ret = pnp_register_driver(&generic_NCR5380_pnp_driver);
> > +   if (!ret)
> > +   pnp_registered = 1;
> >  #endif
> > +   ret = isa_register_driver(&generic_NCR5380_isa_driver, MAX_CARDS);
> > +   if (!ret)
> > +   isa_registered = 1;
> > +
> > +#if !defined(SCSI_G_NCR5380_MEM) && defined(CONFIG_PNP)
> > +   if (pnp_registered)
> > +   ret = 0;
> > +#endif
> > +   if (isa_registered)
> > +   ret = 0;
> > +
> > +   return ret;
> > +}
> > +
> > +static void __exit generic_NCR5380_exit(void)
> > +{
> > +#if !defined(SCSI_G_NCR5380_MEM) && defined(CONFIG_PNP)
> > +   if (pnp_registered)
> > +   pnp_unregister_driver(&generic_NCR5380_pnp_driver);
> > +#endif
> > +   if (isa_registered)
> > +   isa_unregister_driver(&generic_NCR5380_isa_driver);
> > +}
> > +
>
> I find that hard to follow. This should be equivalent and simpler:
>
> static int __init generic_NCR5380_init(void)
> {
>   isa_ret = isa_register_driver(&generic_NCR5380_isa_driver, MAX_CARDS);
> #if !defined(SCSI_G_NCR5380_MEM) && defined(CONFIG_PNP)
>   pnp_ret = pnp_register_driver(&generic_NCR5380_pnp_driver);
>   return pnp_ret ? isa_ret : 0;
> #endif
>   return isa_ret;
> }
>
> static void __exit generic_NCR5380_exit(void)
> {
>   if (!isa_ret)
>   isa_unregister_driver(&generic_NCR5380_isa_driver);
> #if !defined(SCSI_G_NCR5380_MEM) && defined(CONFIG_PNP)
>   if (!pnp_ret)
>   pnp_unregister_driver(&generic_NCR5380_pnp_driver);
> #endif
> }

Doesn't make it any better, IMHO. Good that it's shorter but not cleaner - 
especially this:
>   return pnp_ret ? isa_ret : 0;

Also looking at the _exit function, meaning of isa_ret and pnp_ret is not 
obvious there.

Maybe we should have a module_isa_pnp_driver() macro.

-- 
Ondrej Zary
--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 4/3] g_NCR5380: Merge g_NCR5380 and g_NCR5380_mmio

2016-09-25 Thread Ondrej Zary
Merge the PIO and MMIO code (with the help of ioport_map) in g_NCR5380 and
delete g_NCR5380_mmio.

Signed-off-by: Ondrej Zary 
---
 drivers/scsi/Kconfig  |   32 ++---
 drivers/scsi/g_NCR5380.c  |  257 +++--
 drivers/scsi/g_NCR5380.h  |   33 ++
 drivers/scsi/g_NCR5380_mmio.c |   10 --
 4 files changed, 135 insertions(+), 197 deletions(-)
 delete mode 100644 drivers/scsi/g_NCR5380_mmio.c

diff --git a/drivers/scsi/Kconfig b/drivers/scsi/Kconfig
index 7d1b431..fd1bca1 100644
--- a/drivers/scsi/Kconfig
+++ b/drivers/scsi/Kconfig
@@ -780,40 +780,22 @@ config SCSI_ISCI
  control unit found in the Intel(R) C600 series chipset.
 
 config SCSI_GENERIC_NCR5380
-   tristate "Generic NCR5380/53c400 SCSI PIO support"
+   tristate "Generic NCR5380/53c400 SCSI"
depends on ISA && SCSI
select SCSI_SPI_ATTRS
---help---
- This is a driver for the old NCR 53c80 series of SCSI controllers
- on boards using PIO. Most boards such as the Trantor T130 fit this
- category, along with a large number of ISA 8bit controllers shipped
- for free with SCSI scanners. If you have a PAS16, T128 or DMX3191
- you should select the specific driver for that card rather than
- generic 5380 support.
+ This is a driver for the old NCR 53c80 series of SCSI controllers.
+ Most boards such as the Trantor T130 fit this category, along with
+ a large number of ISA 8bit controllers shipped for free with SCSI
+ scanners. If you have a PAS16, T128 or DMX3191 you should select the
+ specific driver for that card rather than generic 5380 support.
 
  It is explained in section 3.8 of the SCSI-HOWTO, available from
- <http://www.tldp.org/docs.html#howto>.  If it doesn't work out
- of the box, you may have to change some settings in
- .
+ <http://www.tldp.org/docs.html#howto>.
 
  To compile this driver as a module, choose M here: the
  module will be called g_NCR5380.
 
-config SCSI_GENERIC_NCR5380_MMIO
-   tristate "Generic NCR5380/53c400 SCSI MMIO support"
-   depends on ISA && SCSI
-   select SCSI_SPI_ATTRS
-   ---help---
- This is a driver for the old NCR 53c80 series of SCSI controllers
- on boards using memory mapped I/O. 
- It is explained in section 3.8 of the SCSI-HOWTO, available from
- <http://www.tldp.org/docs.html#howto>.  If it doesn't work out
- of the box, you may have to change some settings in
- .
-
- To compile this driver as a module, choose M here: the
- module will be called g_NCR5380_mmio.
-
 config SCSI_IPS
tristate "IBM ServeRAID support"
depends on PCI && SCSI
diff --git a/drivers/scsi/g_NCR5380.c b/drivers/scsi/g_NCR5380.c
index 6cf6b00..7d8fcbf 100644
--- a/drivers/scsi/g_NCR5380.c
+++ b/drivers/scsi/g_NCR5380.c
@@ -50,7 +50,6 @@ MODULE_PARM_DESC(card, "card type (0=NCR5380, 1=NCR53C400, 
2=NCR53C400A, 3=DTC31
 
 MODULE_LICENSE("GPL");
 
-#ifndef SCSI_G_NCR5380_MEM
 /*
  * Configure I/O address of 53C400A or DTC436 by writing magic numbers
  * to ports 0x779 and 0x379.
@@ -72,41 +71,33 @@ static void magic_configure(int idx, u8 irq, u8 magic[])
cfg = 0x80 | idx | (irq << 4);
outb(cfg, 0x379);
 }
-#endif
+
+static unsigned int ncr_53c400a_ports[] __initdata = {
+   0x280, 0x290, 0x300, 0x310, 0x330, 0x340, 0x348, 0x350, 0
+};
+static unsigned int dtc_3181e_ports[] __initdata = {
+   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
+};
 
 static struct Scsi_Host *generic_NCR5380_hw_init(
struct scsi_host_template *tpnt, struct device *pdev,
int base, int irq, int board)
 {
-   unsigned int *ports;
+   unsigned int *ports = NULL;
u8 *magic = NULL;
-#ifndef SCSI_G_NCR5380_MEM
-   int i;
-   int port_idx = -1;
+   int i, port_idx = -1, flags = 0;
unsigned long region_size;
-#endif
-   static unsigned int __initdata ncr_53c400a_ports[] = {
-   0x280, 0x290, 0x300, 0x310, 0x330, 0x340, 0x348, 0x350, 0
-   };
-   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;
 

[PATCH 0/3] g_NCR5380: Modernization

2016-09-24 Thread Ondrej Zary

This small patch series removes deprecated code from g_NCR5380 driver
and converts it from scsi_module.c to scsi_add_host().

Tested with:
HP C2502 (53C400A chip)
Canon FG2-5202 (53C400 chip, memory-mapped)
DTC-3181L (DTCT-436P chip, PnP)

P.S. I don't like the ifdef mess needed for g_NCR5380_mmio. Should I try to
merge the code so g_NCR5380 will support both PIO and MMIO cards (and
g_NCR5380_mmio could be removed)?

-- 
Ondrej Zary
--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 2/3] g_NCR5380: Reduce overrides[] from array to struct

2016-09-24 Thread Ondrej Zary
Remove compile-time card type definition GENERIC_NCR5380_OVERRIDE.
Then remove all code iterating the overrides[] array and reduce it to
struct card.

Signed-off-by: Ondrej Zary 
---
 drivers/scsi/g_NCR5380.c |  351 ++
 1 file changed, 167 insertions(+), 184 deletions(-)

diff --git a/drivers/scsi/g_NCR5380.c b/drivers/scsi/g_NCR5380.c
index 7e50b44e..5162de6 100644
--- a/drivers/scsi/g_NCR5380.c
+++ b/drivers/scsi/g_NCR5380.c
@@ -42,19 +42,12 @@ static int ncr_53c400a;
 static int dtc_3181e;
 static int hp_c2502;
 
-static struct override {
+static struct card {
NCR5380_map_type NCR5380_map_name;
int irq;
int dma;
int board;  /* Use NCR53c400, Ricoh, etc. extensions ? */
-} overrides
-#ifdef GENERIC_NCR5380_OVERRIDE
-[] __initdata = GENERIC_NCR5380_OVERRIDE;
-#else
-[1] __initdata = { { 0,},};
-#endif
-
-#define NO_OVERRIDES ARRAY_SIZE(overrides)
+} card;
 
 #ifndef SCSI_G_NCR5380_MEM
 /*
@@ -85,16 +78,13 @@ static void magic_configure(int idx, u8 irq, u8 magic[])
  * @tpnt: the scsi template
  *
  * Scan for the present of NCR5380, NCR53C400, NCR53C400A, DTC3181E
- * and DTC436(ISAPnP) controllers. If overrides have been set we use
- * them.
+ * and DTC436(ISAPnP) controllers.
  *
  * Locks: none
  */
 
 static int __init generic_NCR5380_detect(struct scsi_host_template *tpnt)
 {
-   static int current_override;
-   int count;
unsigned int *ports;
u8 *magic = NULL;
 #ifndef SCSI_G_NCR5380_MEM
@@ -124,28 +114,25 @@ static int __init generic_NCR5380_detect(struct 
scsi_host_template *tpnt)
 #endif
 
if (ncr_irq)
-   overrides[0].irq = ncr_irq;
+   card.irq = ncr_irq;
if (ncr_dma)
-   overrides[0].dma = ncr_dma;
+   card.dma = ncr_dma;
if (ncr_addr)
-   overrides[0].NCR5380_map_name = (NCR5380_map_type) ncr_addr;
+   card.NCR5380_map_name = (NCR5380_map_type) ncr_addr;
if (ncr_5380)
-   overrides[0].board = BOARD_NCR5380;
+   card.board = BOARD_NCR5380;
else if (ncr_53c400)
-   overrides[0].board = BOARD_NCR53C400;
+   card.board = BOARD_NCR53C400;
else if (ncr_53c400a)
-   overrides[0].board = BOARD_NCR53C400A;
+   card.board = BOARD_NCR53C400A;
else if (dtc_3181e)
-   overrides[0].board = BOARD_DTC3181E;
+   card.board = BOARD_DTC3181E;
else if (hp_c2502)
-   overrides[0].board = BOARD_HP_C2502;
+   card.board = BOARD_HP_C2502;
 #ifndef SCSI_G_NCR5380_MEM
-   if (!current_override && isapnp_present()) {
+   if (isapnp_present()) {
struct pnp_dev *dev = NULL;
-   count = 0;
while ((dev = pnp_find_dev(NULL, ISAPNP_VENDOR('D', 'T', 'C'), 
ISAPNP_FUNCTION(0x436e), dev))) {
-   if (count >= NO_OVERRIDES)
-   break;
if (pnp_device_attach(dev) < 0)
continue;
if (pnp_activate_dev(dev) < 0) {
@@ -159,202 +146,198 @@ static int __init generic_NCR5380_detect(struct 
scsi_host_template *tpnt)
continue;
}
if (pnp_irq_valid(dev, 0))
-   overrides[count].irq = pnp_irq(dev, 0);
+   card.irq = pnp_irq(dev, 0);
else
-   overrides[count].irq = NO_IRQ;
+   card.irq = NO_IRQ;
if (pnp_dma_valid(dev, 0))
-   overrides[count].dma = pnp_dma(dev, 0);
+   card.dma = pnp_dma(dev, 0);
else
-   overrides[count].dma = DMA_NONE;
-   overrides[count].NCR5380_map_name = (NCR5380_map_type) 
pnp_port_start(dev, 0);
-   overrides[count].board = BOARD_DTC3181E;
-   count++;
+   card.dma = DMA_NONE;
+   card.NCR5380_map_name = (NCR5380_map_type) 
pnp_port_start(dev, 0);
+   card.board = BOARD_DTC3181E;
+   break;
}
}
 #endif
 
-   for (count = 0; current_override < NO_OVERRIDES; ++current_override) {
-   if (!(overrides[current_override].NCR5380_map_name))
-   continue;
+   if (!(card.NCR5380_map_name))
+   return 0;
 
-   ports = NULL;
-   flags = 0;
-   switch (overrides[current_override].board) {
-   case BOARD_NCR5380:
-   flags = FLAG_NO_PSEUDO_DMA | FLAG_DMA_FIXUP;
- 

[PATCH 1/3] g_NCR5380: Remove deprecated __setup

2016-09-24 Thread Ondrej Zary
Remove deprecated __setup for parsing command line parameters.
g_NCR5380.* parameters could be used instead.

Signed-off-by: Ondrej Zary 
---
 drivers/scsi/g_NCR5380.c |  135 --
 1 file changed, 135 deletions(-)

diff --git a/drivers/scsi/g_NCR5380.c b/drivers/scsi/g_NCR5380.c
index 516bd6c..7e50b44e 100644
--- a/drivers/scsi/g_NCR5380.c
+++ b/drivers/scsi/g_NCR5380.c
@@ -56,136 +56,6 @@ static struct override {
 
 #define NO_OVERRIDES ARRAY_SIZE(overrides)
 
-#ifndef MODULE
-
-/**
- * internal_setup  -   handle lilo command string override
- * @board: BOARD_* identifier for the board
- * @str: unused
- * @ints: numeric parameters
- *
- * Do LILO command line initialization of the overrides array. Display
- * errors when needed
- *
- * Locks: none
- */
-
-static void __init internal_setup(int board, char *str, int *ints)
-{
-   static int commandline_current;
-   switch (board) {
-   case BOARD_NCR5380:
-   if (ints[0] != 2 && ints[0] != 3) {
-   printk(KERN_ERR "generic_NCR5380_setup : usage 
ncr5380=" STRVAL(NCR5380_map_name) ",irq,dma\n");
-   return;
-   }
-   break;
-   case BOARD_NCR53C400:
-   if (ints[0] != 2) {
-   printk(KERN_ERR "generic_NCR53C400_setup : usage 
ncr53c400=" STRVAL(NCR5380_map_name) ",irq\n");
-   return;
-   }
-   break;
-   case BOARD_NCR53C400A:
-   if (ints[0] != 2) {
-   printk(KERN_ERR "generic_NCR53C400A_setup : usage 
ncr53c400a=" STRVAL(NCR5380_map_name) ",irq\n");
-   return;
-   }
-   break;
-   case BOARD_DTC3181E:
-   if (ints[0] != 2) {
-   printk("generic_DTC3181E_setup : usage dtc3181e=" 
STRVAL(NCR5380_map_name) ",irq\n");
-   return;
-   }
-   break;
-   }
-
-   if (commandline_current < NO_OVERRIDES) {
-   overrides[commandline_current].NCR5380_map_name = 
(NCR5380_map_type) ints[1];
-   overrides[commandline_current].irq = ints[2];
-   if (ints[0] == 3)
-   overrides[commandline_current].dma = ints[3];
-   else
-   overrides[commandline_current].dma = DMA_NONE;
-   overrides[commandline_current].board = board;
-   ++commandline_current;
-   }
-}
-
-
-/**
- * do_NCR53C80_setup   -   set up entry point
- * @str: unused
- *
- * Setup function invoked at boot to parse the ncr5380= command
- * line.
- */
-
-static int __init do_NCR5380_setup(char *str)
-{
-   int ints[10];
-
-   get_options(str, ARRAY_SIZE(ints), ints);
-   internal_setup(BOARD_NCR5380, str, ints);
-   return 1;
-}
-
-/**
- * do_NCR53C400_setup  -   set up entry point
- * @str: unused
- * @ints: integer parameters from kernel setup code
- *
- * Setup function invoked at boot to parse the ncr53c400= command
- * line.
- */
-
-static int __init do_NCR53C400_setup(char *str)
-{
-   int ints[10];
-
-   get_options(str, ARRAY_SIZE(ints), ints);
-   internal_setup(BOARD_NCR53C400, str, ints);
-   return 1;
-}
-
-/**
- * do_NCR53C400A_setup -   set up entry point
- * @str: unused
- * @ints: integer parameters from kernel setup code
- *
- * Setup function invoked at boot to parse the ncr53c400a= command
- * line.
- */
-
-static int __init do_NCR53C400A_setup(char *str)
-{
-   int ints[10];
-
-   get_options(str, ARRAY_SIZE(ints), ints);
-   internal_setup(BOARD_NCR53C400A, str, ints);
-   return 1;
-}
-
-/**
- * do_DTC3181E_setup   -   set up entry point
- * @str: unused
- * @ints: integer parameters from kernel setup code
- *
- * Setup function invoked at boot to parse the dtc3181e= command
- * line.
- */
-
-static int __init do_DTC3181E_setup(char *str)
-{
-   int ints[10];
-
-   get_options(str, ARRAY_SIZE(ints), ints);
-   internal_setup(BOARD_DTC3181E, str, ints);
-   return 1;
-}
-
-#endif
-
 #ifndef SCSI_G_NCR5380_MEM
 /*
  * Configure I/O address of 53C400A or DTC436 by writing magic numbers
@@ -741,8 +611,3 @@ static struct isapnp_device_id id_table[] = {
 
 MODULE_DEVICE_TABLE(isapnp, id_table);
 #endif
-
-__setup("ncr5380=", do_NCR5380_setup);
-__setup("ncr53c400=", do_NCR53C400_setup);
-__setup("ncr53c400a=", do_NCR53C400A_setup);
-__setup("dtc3181e=", do_DTC3181E_setup);
-- 
Ondrej Zary

--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 3/3] g_NCR5380: Stop using scsi_module.c

2016-09-24 Thread Ondrej Zary
Convert g_NCR5380 to use scsi_add_host instead of scsi_module.c
Use pnp_driver and isa_driver to manage cards.

Signed-off-by: Ondrej Zary 
---
 drivers/scsi/g_NCR5380.c |  310 +-
 drivers/scsi/g_NCR5380.h |8 --
 2 files changed, 169 insertions(+), 149 deletions(-)

diff --git a/drivers/scsi/g_NCR5380.c b/drivers/scsi/g_NCR5380.c
index 5162de6..6cf6b00 100644
--- a/drivers/scsi/g_NCR5380.c
+++ b/drivers/scsi/g_NCR5380.c
@@ -30,24 +30,25 @@
 #include "NCR5380.h"
 #include 
 #include 
-#include 
+#include 
+#include 
 #include 
 
-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 int hp_c2502;
-
-static struct card {
-   NCR5380_map_type NCR5380_map_name;
-   int irq;
-   int dma;
-   int board;  /* Use NCR53c400, Ricoh, etc. extensions ? */
-} card;
+#define MAX_CARDS 8
+
+static int irq[] = { 0, 0, 0, 0, 0, 0, 0, 0 };
+module_param_array(irq, int, NULL, 0);
+MODULE_PARM_DESC(irq, "IRQ number(s)");
+
+static int base[] = { 0, 0, 0, 0, 0, 0, 0, 0 };
+module_param_array(base, int, NULL, 0);
+MODULE_PARM_DESC(base, "base address(es)");
+
+static int card[] = { -1, -1, -1, -1, -1, -1, -1, -1 };
+module_param_array(card, int, NULL, 0);
+MODULE_PARM_DESC(card, "card type (0=NCR5380, 1=NCR53C400, 2=NCR53C400A, 
3=DTC3181E, 4=HP C2502)");
+
+MODULE_LICENSE("GPL");
 
 #ifndef SCSI_G_NCR5380_MEM
 /*
@@ -73,17 +74,9 @@ static void magic_configure(int idx, u8 irq, u8 magic[])
 }
 #endif
 
-/**
- * generic_NCR5380_detect  -   look for NCR5380 controllers
- * @tpnt: the scsi template
- *
- * Scan for the present of NCR5380, NCR53C400, NCR53C400A, DTC3181E
- * and DTC436(ISAPnP) controllers.
- *
- * Locks: none
- */
-
-static int __init generic_NCR5380_detect(struct scsi_host_template *tpnt)
+static struct Scsi_Host *generic_NCR5380_hw_init(
+   struct scsi_host_template *tpnt, struct device *pdev,
+   int base, int irq, int board)
 {
unsigned int *ports;
u8 *magic = NULL;
@@ -108,64 +101,13 @@ static int __init generic_NCR5380_detect(struct 
scsi_host_template *tpnt)
struct Scsi_Host *instance;
struct NCR5380_hostdata *hostdata;
 #ifdef SCSI_G_NCR5380_MEM
-   unsigned long base;
void __iomem *iomem;
resource_size_t iomem_size;
 #endif
 
-   if (ncr_irq)
-   card.irq = ncr_irq;
-   if (ncr_dma)
-   card.dma = ncr_dma;
-   if (ncr_addr)
-   card.NCR5380_map_name = (NCR5380_map_type) ncr_addr;
-   if (ncr_5380)
-   card.board = BOARD_NCR5380;
-   else if (ncr_53c400)
-   card.board = BOARD_NCR53C400;
-   else if (ncr_53c400a)
-   card.board = BOARD_NCR53C400A;
-   else if (dtc_3181e)
-   card.board = BOARD_DTC3181E;
-   else if (hp_c2502)
-   card.board = BOARD_HP_C2502;
-#ifndef SCSI_G_NCR5380_MEM
-   if (isapnp_present()) {
-   struct pnp_dev *dev = NULL;
-   while ((dev = pnp_find_dev(NULL, ISAPNP_VENDOR('D', 'T', 'C'), 
ISAPNP_FUNCTION(0x436e), dev))) {
-   if (pnp_device_attach(dev) < 0)
-   continue;
-   if (pnp_activate_dev(dev) < 0) {
-   printk(KERN_ERR "dtc436e probe: activate 
failed\n");
-   pnp_device_detach(dev);
-   continue;
-   }
-   if (!pnp_port_valid(dev, 0)) {
-   printk(KERN_ERR "dtc436e probe: no valid 
port\n");
-   pnp_device_detach(dev);
-   continue;
-   }
-   if (pnp_irq_valid(dev, 0))
-   card.irq = pnp_irq(dev, 0);
-   else
-   card.irq = NO_IRQ;
-   if (pnp_dma_valid(dev, 0))
-   card.dma = pnp_dma(dev, 0);
-   else
-   card.dma = DMA_NONE;
-   card.NCR5380_map_name = (NCR5380_map_type) 
pnp_port_start(dev, 0);
-   card.board = BOARD_DTC3181E;
-   break;
-   }
-   }
-#endif
-
-   if (!(card.NCR5380_map_name))
-   return 0;
-
ports = NULL;
flags = 0;
-   switch (card.board) {
+   switch (board) {
case BOARD_NCR5380:
flags = FLAG_NO_PSEUDO_DMA | FLAG_DMA_FIXUP;
break;
@@ -191,17 +133,20 @@ static int __init generic_NCR5380_detect(struct 
scsi_host_template *tpnt)
magic_configure(-

Re: RFC: should we deprecate unmaintained isa-only drivers?

2016-09-11 Thread Ondrej Zary
On Sunday 11 September 2016 19:01:55 Christoph Hellwig wrote:
> On Wed, Mar 25, 2015 at 09:52:53PM +0100, Ondrej Zary wrote:
> > >  - wd7000
> > >  - aha1542
> > >  - in2000
> > >  - NCR53c406
> > >  - sym53c416
> > >  - u14-34f
> > >  - ultrastor
> >
> > NCR53c406a and sym53c416 look very similar. The register numbers and
> > commands are almost the same so NCR53c406 support could probably be added
> > to sym53c416 driver (looks better of the two) and NCR53c406a driver
> > removed. Now I have cards with both chips so I'll try.
>
> Did you get a chance to look at this project?

At first try (with some quick hacking only), the 53c406 card didn't work with 
sym53c416 driver. I haven't had time for more serious work back then. 
Hopefully I'll try harder soon.

-- 
Ondrej Zary
--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: status of NCR5380-based ISA drivers

2016-09-11 Thread Ondrej Zary
On Sunday 11 September 2016 19:12:49 Christoph Hellwig wrote:
> Hi all,
>
> you seem to the currently active NCR580 cabal.  Which frontends to NCR5380
> do you test at the moment, or could you test?
>
> NCR5380-based ISA drivers make up a significant part of those drivers still
> using scsi_module.c after it's 15 year deprecation period, and I'd like to
> either move them to this century or to the dust bin.
>
> The drivers in question are: dtc, g_NCR5380, pas16 and t128.
>
> Thanks,
>   Christoph

I have the HW to test g_NCR5380 - it currently works fine as it did never 
before.
I started a patch to for scsi_module.c removal (and other good things) but 
haven't had time to finish it. Hopefully, it will be ready soon.

-- 
Ondrej Zary
--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v3 00/23] ncr5380: Eliminate macros, reduce code duplication, fix bugs etc

2016-03-22 Thread Ondrej Zary
On Monday 21 March 2016 03:31:49 Finn Thain wrote:
> 
> This patch series has more macro elimination and some tweaks to the
> DMA hooks so that all the wrapper drivers can share the same core
> DMA algorithm. This resolves the major discrepancies between the two
> core drivers, which relate to code conditional on the REAL_DMA and
> PSEUDO_DMA macros.
> 
> After all the wrapper drivers agree on the DMA hook api, the core driver
> fork gets resolved. NCR5380.c is adopted by atari_scsi and sun3_scsi and
> atari_NCR5380.c is then deleted.
> 
> Historically, the 5380 drivers suffered from over-use of conditional
> compilation, which caused the compile-time configuration space to explode,
> leading to core driver code that was practically untestable, unmaintainable
> and difficult to reason about. It also prevented driver modules from
> sharing object code.
> 
> Along with REAL_DMA, REAL_DMA_POLL and PSEUDO_DMA, most of the remaining
> macros are also eradicated, such as CONFIG_SCSI_GENERIC_NCR53C400,
> SUPPORT_TAGS, DONT_USE_INTR, AUTOPROBE_IRQ and BIOSPARAM.
> 
> Also in this patch series, some duplicated documentation is removed and
> the PDMA implementation in mac_scsi finally gets fixed.
> 
> This patch series was tested by exercising the dmx3191d and mac_scsi modules
> on suitable hardware. Michael has tested atari_scsi on an Atari Falcon.
> Help with driver testing on ISA cards is sought as I don't have such
> hardware. Likewise RiscPC ecards and Sun 3.

Tested on HP C2502 (53C400A chip), Canon FG2-5202 (53C400 chip) and DTC-3181L
(DTCT-436P chip) ISA cards - everything works fine!

Thanks.

Tested-by: Ondrej Zary 

HP C2502:
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 { 
}, options { }

Canon FG2-5202:
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 
{ }, options { }

DTC-3181L:
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 { 
}, options { }

-- 
Ondrej Zary
--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v3 00/77] More fixes, cleanup and modernization for NCR5380 drivers

2015-12-22 Thread Ondrej Zary
On Tuesday 22 December 2015 02:17:38 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 over 700 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.
> 
> All patches to all NCR5380 drivers (x86, ARM, m68k) have been compile-
> tested. The mac_scsi, dmx3191d, g_NCR5380 and atari_scsi modules were
> regression tested on suitable hardware.

Tested on HP C2502 (53C400A chip), Canon FG2-5202 (53C400 chip) and DTC-3181L 
(DTCT-436P chip) ISA cards - everything works fine!

Thanks.

Tested-by: Ondrej Zary 

-- 
Ondrej Zary
--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v2 74/71] ncr5380: Enable PDMA for NCR53C400A

2015-12-09 Thread Ondrej Zary
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 
> > ---
> >  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
--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v3 78/71] ncr5380: Add support for HP 53C400A-based cards (C2502)

2015-12-09 Thread Ondrej Zary
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 
---
 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);
 

Re: [patch RESEND] atp870u: 64 bit bug in atp885_init()

2015-12-09 Thread Ondrej Zary
On Wednesday 09 December 2015 12:53:39 One Thousand Gnomes wrote:
> On Wed, 9 Dec 2015 13:24:53 +0300
> Dan Carpenter  wrote:
> 
> > On 64 bit CPUs there is a memory corruption bug on probe().  It should
> > be a u32 pointer instead of an unsigned long pointer or we write past
> > the end of the setupdata[] array.
> > 
> > Signed-off-by: Dan Carpenter 
> > Reviewed-by: Hannes Reinecke 
> > ---
> > Resending because we have shuffled the code around so the patch needed
> > to be refreshed against linux-next.  Although I do wonder why we are
> > still working on this code since it has never worked on 64 bit systems
> > so probably all the users gave up a decade ago.
> 
> So this is untested ? If so please make it very clear in the commit
> message because the kernel is IMHO getting too full of polished, neat,
> recently modified, never tested, never used code.
> 
> I agree it would be better if the driver was simply deleted. I've not
> even seen an ATP870 bug report in years.

Maybe because it worked. Although the code was horrible. I've done some big 
changes to this driver recently (tested, of course).
I can't test this patch as I don't have ATP885 card, only ATP870.

-- 
Ondrej Zary
--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v2 78/71] ncr5380: Add support for HP 53C400A-based cards (C2502)

2015-12-09 Thread Ondrej Zary
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 
> > ---
> >  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 fl

[PATCH v2 78/71] ncr5380: Add support for HP 53C400A-based cards (C2502)

2015-12-07 Thread Ondrej Zary
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 
---
 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 @@ sta

Re: [PATCH v2 77/71] ncr5380: Fix wait for 53C80 registers registers after PDMA

2015-12-07 Thread Ondrej Zary
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 
> > ---
> >  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
--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v3 76/71] ncr5380: Enable PDMA for DTC chips

2015-12-06 Thread Ondrej Zary
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 
---
 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 N

[PATCH v2 77/71] ncr5380: Fix wait for 53C80 registers registers after PDMA

2015-12-06 Thread Ondrej Zary
The check for 53C80 registers accessibility was commented out because
it was broken (inverted). Fix and enable it.

Signed-off-by: Ondrej Zary 
---
 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

--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v2 76/71] ncr5380: Enable PDMA for DTC chips

2015-12-06 Thread Ondrej Zary
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 
---
 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 + hostda

Re: [PATCH 76/71] ncr5380: Enable PDMA for DTC chips

2015-12-06 Thread Ondrej Zary
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 
> > ---
> >  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 ||
> > -   overri

  1   2   3   4   >