diff mbox

[v7] scsi: new zorro_esp.c for Amiga Zorro NCR53C9x boards

Message ID 1523155532-20913-1-git-send-email-schmitzmic@gmail.com (mailing list archive)
State Changes Requested
Headers show

Commit Message

Michael Schmitz April 8, 2018, 2:45 a.m. UTC
New combined SCSI driver for all ESP based Zorro SCSI boards for
m68k Amiga.

Code largely based on board specific parts of the old drivers (blz1230.c,
blz2060.c, cyberstorm.c, cyberstormII.c, fastlane.c which were removed
after the 2.6 kernel series for lack of maintenance) with contributions
by Tuomas Vainikka (TCQ bug tests and workaround) and Finn Thain (TCQ
bugfix by use of PIO in extended message in transfer).

New Kconfig option and Makefile entries for new Amiga Zorro ESP SCSI
driver included in this patch.

Use DMA transfers wherever possible, with board-specific DMA set-up
functions copied from the old driver code. Three byte reselection messages
do appear to cause DMA timeouts. So wire up a PIO transfer routine for
these instead. esp_reselect_with_tag explicitly sets esp->cmd_block_dma as
target address for the message bytes but PIO requires a virtual address.
Substiute kernel virtual address esp->cmd_block in PIO transfer call if
DMA address is esp->cmd_block_dma and phase is message in.

PIO code taken from mac_esp.c where the reselection timeout issue was
debugged and fixed first, with minor macro and function rename.

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

---

Changes since v1:

Fixed issues raised by Finn Thain in initial code review:

- use KBUILD_MODNAME for driver name string.
- use pr_fmt() for pr_* format prefix.
- clean up DMA error reporting: clear error flag before each DMA
  operation, set error flag on PIO error. Don't test phase in dma_err hook.
- change confusing comment about semantics of read flag, add comments
  indicating DMA direction to DMA setup hooks.
- drop spurious braces around switch clauses.
- lift cfreq setting out of ID switch clauses.
- fix indentation.
- fix error codes on probe fail.
- drop check for board ID when unmapping DMA regs in error handling:
  the ioaddr > 0xffffff test already catches all cases where the DMA
  registers were ioremapped.
- dynamically alloc zorro_private_data.
- fix use of driver_data field (don't mix host and zorro_esp_priv
  pointers). Note: require esp pointer in zorro_esp_priv to find host
  pointer!
- back out phase bits changes to pio_cmd !write branch introduced
  to cope with ESP SELAS command. We don't use that code so keep
  it in sync with Finn's version.
- use esp_ops.dma_length_limit() to limit transfer size. After review
  of old driver code, use 0xffffff max transfer size throughout.

Fixed issues raised by Geert Uytterhoven:

- dynamically alloc zorro_private_data, store as device drvdata.
- store ctrl_data for CyberStormI in driver private data.
- use dma_sync_single_for_device() instead of cache_push/clear.
- handle case of duplicate board identity - check whether board is
  Zorro III or Zorro II (use ROM resource data for this). Also fix
  up DMA mask for Zorro II boards to 32 bits (these are really CPU
  expansion slot boards).
- remove zorro3 field from driver_data struct (now in private data).
- add braces around ambiguous if - else construct.
- use named structs instead of array for board config data.
- use scsi_option driver data flag for boards with optional ESP.

Other improvements and bugfixes

- fix Zorro device table error (duplicate ID used, also raised
  by Kars de Jong).
- error code fixup in error handling path.
- add separate DMA setup for Blizzard 1230 II board.
- add support for Cyberstorm II board.
- add register structs and DMA setup for Zorro III Fastlane board,
  following logic from old fastlane.c driver. Wire up Fastlane DMA
  and interrupt status routines, map the necessary low 24 bit board
  address space used for DMA target address setting. Clean up DMA
  register space ioremap() branch for Zorro III boards (currently
  Fastlane only) to end confusion about what to do in error recovery.
- use esp_ops.fastlane_esp_dma_invalidate() on Fastlane (and skip
  fastlane_esp_reset_dma() in DMA setup).
- credit Tuomas Vainikka for contributing Blizzard 1230 code (and
  testing).
- clarify comment about unsupported Oktagon SCSI board.
- remove unused const definitions carried over from old driver.

Changes since v2:

- add SPDX-License-Identifier.
- remove unused ratelimit.h.
- drop phys_to_virt() in PIO transfer routine, after ensuring PIO is only
  used for message in transfers to esp->command_block. This obviates any
  need for finding the virtual address corresponding to a DMA handle.
- drop BUG_ON(!(cmd & ESP_CMD_DMA)) assertion in DMA setup. Short of changes
  to the core ESP driver, this can never trigger.
- make ioremap() of DMA address range conditional on zep->zorro3 and use
  that same condition to unmap in error handling and driver exit.
  Omit board ID test as we only support a single Zorro III board, and add
  comment on what to do when adding support for more boards.
- free driver private data in driver exit.
- various whitespace related cleanup.

Changes since v3:

Finn  Thain:
- substitute esp->command_block for transfer address in each board DMA
  set-up, instead of in PIO transfer function.
- use kzalloc for struct zorro_esp_priv.
- clarify comment regarding selecting between Blizzard 1230 II or
  board (both share the ID with the Fastlane board).
- use dev_get|set_drvdata instead of zorro_get|set_drvdata wrapper.
- remove redundant comments.

Geert Uytterhoeven:
- use readb()/writeb() to access DMA registers, obviating the need for
  declaring register structs volatile.
- use const for board config and driver data table.
- drop ZORRO_ESP_GET_PRIV macro.
- add comments to clarify use of addr and fifo variables in PIO macros.
- add braces to Zorro II branch (DMA mask fixup).
- define board ops irq_pending, dma_invalidate and send_dma_cmd via
  function pointers in driver data.

Tuomas Vainikka:
- fix wrong config description in Kconfig (from NCR7xx driver).

Changes since v4:

- change tag line

Kars de Jong:
- fix misspelling of Blizzard 1230 as 1320 in config description

Changes since v5:

Christoph Hellwig:
- fix comment style
- drop initialization to zero in driver data init
- fix alignment in struct declarations
- drop braces around asm macros
- change board_base type to void __iomem *
- drop unneeded void __iomem * cast from ZTWO_VADDR() use
- add comment to explain why ZTWO_VADDR() use is safe
- move board specific functions to per-board esp_ops

Changes since v6:

Finn Thain:
- use z_writel to avoid sparse warnings in Fastlane DMA functions

---
 drivers/scsi/Kconfig     |   14 +
 drivers/scsi/Makefile    |    1 +
 drivers/scsi/zorro_esp.c | 1166 ++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 1181 insertions(+), 0 deletions(-)
 create mode 100644 drivers/scsi/zorro_esp.c

Comments

Christoph Hellwig April 9, 2018, 7:50 a.m. UTC | #1
On Sun, Apr 08, 2018 at 02:45:32PM +1200, Michael Schmitz wrote:
> New combined SCSI driver for all ESP based Zorro SCSI boards for
> m68k Amiga.
> 
> Code largely based on board specific parts of the old drivers (blz1230.c,
> blz2060.c, cyberstorm.c, cyberstormII.c, fastlane.c which were removed
> after the 2.6 kernel series for lack of maintenance) with contributions
> by Tuomas Vainikka (TCQ bug tests and workaround) and Finn Thain (TCQ
> bugfix by use of PIO in extended message in transfer).
> 
> New Kconfig option and Makefile entries for new Amiga Zorro ESP SCSI
> driver included in this patch.
> 
> Use DMA transfers wherever possible, with board-specific DMA set-up
> functions copied from the old driver code. Three byte reselection messages
> do appear to cause DMA timeouts. So wire up a PIO transfer routine for
> these instead. esp_reselect_with_tag explicitly sets esp->cmd_block_dma as
> target address for the message bytes but PIO requires a virtual address.
> Substiute kernel virtual address esp->cmd_block in PIO transfer call if
> DMA address is esp->cmd_block_dma and phase is message in.
> 
> PIO code taken from mac_esp.c where the reselection timeout issue was
> debugged and fixed first, with minor macro and function rename.
> 
> Signed-off-by: Michael Schmitz <schmitzmic@gmail.com>
> Reviewed-by: Finn Thain <fthain@telegraphics.com.au>
> 
> ---
> 
> Changes since v1:
> 
> Fixed issues raised by Finn Thain in initial code review:
> 
> - use KBUILD_MODNAME for driver name string.
> - use pr_fmt() for pr_* format prefix.
> - clean up DMA error reporting: clear error flag before each DMA
>   operation, set error flag on PIO error. Don't test phase in dma_err hook.
> - change confusing comment about semantics of read flag, add comments
>   indicating DMA direction to DMA setup hooks.
> - drop spurious braces around switch clauses.
> - lift cfreq setting out of ID switch clauses.
> - fix indentation.
> - fix error codes on probe fail.
> - drop check for board ID when unmapping DMA regs in error handling:
>   the ioaddr > 0xffffff test already catches all cases where the DMA
>   registers were ioremapped.
> - dynamically alloc zorro_private_data.
> - fix use of driver_data field (don't mix host and zorro_esp_priv
>   pointers). Note: require esp pointer in zorro_esp_priv to find host
>   pointer!
> - back out phase bits changes to pio_cmd !write branch introduced
>   to cope with ESP SELAS command. We don't use that code so keep
>   it in sync with Finn's version.
> - use esp_ops.dma_length_limit() to limit transfer size. After review
>   of old driver code, use 0xffffff max transfer size throughout.
> 
> Fixed issues raised by Geert Uytterhoven:
> 
> - dynamically alloc zorro_private_data, store as device drvdata.
> - store ctrl_data for CyberStormI in driver private data.
> - use dma_sync_single_for_device() instead of cache_push/clear.
> - handle case of duplicate board identity - check whether board is
>   Zorro III or Zorro II (use ROM resource data for this). Also fix
>   up DMA mask for Zorro II boards to 32 bits (these are really CPU
>   expansion slot boards).
> - remove zorro3 field from driver_data struct (now in private data).
> - add braces around ambiguous if - else construct.
> - use named structs instead of array for board config data.
> - use scsi_option driver data flag for boards with optional ESP.
> 
> Other improvements and bugfixes
> 
> - fix Zorro device table error (duplicate ID used, also raised
>   by Kars de Jong).
> - error code fixup in error handling path.
> - add separate DMA setup for Blizzard 1230 II board.
> - add support for Cyberstorm II board.
> - add register structs and DMA setup for Zorro III Fastlane board,
>   following logic from old fastlane.c driver. Wire up Fastlane DMA
>   and interrupt status routines, map the necessary low 24 bit board
>   address space used for DMA target address setting. Clean up DMA
>   register space ioremap() branch for Zorro III boards (currently
>   Fastlane only) to end confusion about what to do in error recovery.
> - use esp_ops.fastlane_esp_dma_invalidate() on Fastlane (and skip
>   fastlane_esp_reset_dma() in DMA setup).
> - credit Tuomas Vainikka for contributing Blizzard 1230 code (and
>   testing).
> - clarify comment about unsupported Oktagon SCSI board.
> - remove unused const definitions carried over from old driver.
> 
> Changes since v2:
> 
> - add SPDX-License-Identifier.
> - remove unused ratelimit.h.
> - drop phys_to_virt() in PIO transfer routine, after ensuring PIO is only
>   used for message in transfers to esp->command_block. This obviates any
>   need for finding the virtual address corresponding to a DMA handle.
> - drop BUG_ON(!(cmd & ESP_CMD_DMA)) assertion in DMA setup. Short of changes
>   to the core ESP driver, this can never trigger.
> - make ioremap() of DMA address range conditional on zep->zorro3 and use
>   that same condition to unmap in error handling and driver exit.
>   Omit board ID test as we only support a single Zorro III board, and add
>   comment on what to do when adding support for more boards.
> - free driver private data in driver exit.
> - various whitespace related cleanup.
> 
> Changes since v3:
> 
> Finn  Thain:
> - substitute esp->command_block for transfer address in each board DMA
>   set-up, instead of in PIO transfer function.
> - use kzalloc for struct zorro_esp_priv.
> - clarify comment regarding selecting between Blizzard 1230 II or
>   board (both share the ID with the Fastlane board).
> - use dev_get|set_drvdata instead of zorro_get|set_drvdata wrapper.
> - remove redundant comments.
> 
> Geert Uytterhoeven:
> - use readb()/writeb() to access DMA registers, obviating the need for
>   declaring register structs volatile.
> - use const for board config and driver data table.
> - drop ZORRO_ESP_GET_PRIV macro.
> - add comments to clarify use of addr and fifo variables in PIO macros.
> - add braces to Zorro II branch (DMA mask fixup).
> - define board ops irq_pending, dma_invalidate and send_dma_cmd via
>   function pointers in driver data.
> 
> Tuomas Vainikka:
> - fix wrong config description in Kconfig (from NCR7xx driver).
> 
> Changes since v4:
> 
> - change tag line
> 
> Kars de Jong:
> - fix misspelling of Blizzard 1230 as 1320 in config description
> 
> Changes since v5:
> 
> Christoph Hellwig:
> - fix comment style
> - drop initialization to zero in driver data init
> - fix alignment in struct declarations
> - drop braces around asm macros
> - change board_base type to void __iomem *
> - drop unneeded void __iomem * cast from ZTWO_VADDR() use
> - add comment to explain why ZTWO_VADDR() use is safe
> - move board specific functions to per-board esp_ops
> 
> Changes since v6:
> 
> Finn Thain:
> - use z_writel to avoid sparse warnings in Fastlane DMA functions
> 
> ---
>  drivers/scsi/Kconfig     |   14 +
>  drivers/scsi/Makefile    |    1 +
>  drivers/scsi/zorro_esp.c | 1166 ++++++++++++++++++++++++++++++++++++++++++++++
>  3 files changed, 1181 insertions(+), 0 deletions(-)
>  create mode 100644 drivers/scsi/zorro_esp.c
> 
> diff --git a/drivers/scsi/Kconfig b/drivers/scsi/Kconfig
> index 8a739b7..94eb3f3 100644
> --- a/drivers/scsi/Kconfig
> +++ b/drivers/scsi/Kconfig
> @@ -1462,6 +1462,20 @@ config SCSI_ZORRO7XX
>  	      accelerator card for the Amiga 1200,
>  	    - the SCSI controller on the GVP Turbo 040/060 accelerator.
>  
> +config SCSI_ZORRO_ESP
> +	tristate "Zorro ESP SCSI support"
> +	depends on ZORRO && SCSI
> +	select SCSI_SPI_ATTRS
> +	help
> +	  Support for various NCR53C9x (ESP) based SCSI controllers on Zorro
> +	  expansion boards for the Amiga.
> +	  This includes:
> +	    - the Phase5 Blizzard 1230 II and IV SCSI controllers,
> +	    - the Phase5 Blizzard 2060 SCSI controller,
> +	    - the Phase5 Blizzard Cyberstorm and Cyberstorm II SCSI
> +	      controllers,
> +	    - the Fastlane Zorro III SCSI controller.
> +
>  config ATARI_SCSI
>  	tristate "Atari native SCSI support"
>  	depends on ATARI && SCSI
> diff --git a/drivers/scsi/Makefile b/drivers/scsi/Makefile
> index de1b3fc..20992d7 100644
> --- a/drivers/scsi/Makefile
> +++ b/drivers/scsi/Makefile
> @@ -48,6 +48,7 @@ obj-$(CONFIG_INFINIBAND_ISER) 	+= libiscsi.o
>  obj-$(CONFIG_ISCSI_BOOT_SYSFS)	+= iscsi_boot_sysfs.o
>  obj-$(CONFIG_SCSI_A4000T)	+= 53c700.o	a4000t.o
>  obj-$(CONFIG_SCSI_ZORRO7XX)	+= 53c700.o	zorro7xx.o
> +obj-$(CONFIG_SCSI_ZORRO_ESP)	+= esp_scsi.o	zorro_esp.o
>  obj-$(CONFIG_A3000_SCSI)	+= a3000.o	wd33c93.o
>  obj-$(CONFIG_A2091_SCSI)	+= a2091.o	wd33c93.o
>  obj-$(CONFIG_GVP11_SCSI)	+= gvp11.o	wd33c93.o
> diff --git a/drivers/scsi/zorro_esp.c b/drivers/scsi/zorro_esp.c
> new file mode 100644
> index 0000000..9fae980
> --- /dev/null
> +++ b/drivers/scsi/zorro_esp.c
> @@ -0,0 +1,1166 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * zorro_esp.c: ESP front-end for Amiga ZORRO SCSI systems.

We usually avoid mentioning the file name of the actual file in
comments.

> +	{
> +		.id = ZORRO_PROD_PHASE5_BLIZZARD_1230_II_FASTLANE_Z3_CYBERSCSI_CYBERSTORM060,

In PCI Land we've usually stopped using PCI IDs unless they are used
in multiple 

> +		.driver_data = (unsigned long)&blizzard1230II_data,

What most (or at least many) drivers do in PCI land is to just use
an enum of types in the driver_Data field and use that as an index for
for decisions later.  It seems like that might be the cleaner method
here as well.

Except for these nitpicks this looks great to me:

Reviewed-by: Christoph Hellwig <hch@lst.de>
Geert Uytterhoeven April 9, 2018, 9:51 a.m. UTC | #2
Hi Christoph,

On Mon, Apr 9, 2018 at 9:50 AM, Christoph Hellwig <hch@infradead.org> wrote:
> On Sun, Apr 08, 2018 at 02:45:32PM +1200, Michael Schmitz wrote:
>> --- /dev/null
>> +++ b/drivers/scsi/zorro_esp.c

>> +             .driver_data = (unsigned long)&blizzard1230II_data,
>
> What most (or at least many) drivers do in PCI land is to just use
> an enum of types in the driver_Data field and use that as an index for
> for decisions later.  It seems like that might be the cleaner method
> here as well.

That may work fine for a small number of differences.
For more differences, the pointer to the feature struct is what most DT
drivers use (of_device_id.data is a const void *).

Gr{oetje,eeting}s,

                        Geert
Michael Schmitz April 10, 2018, 2:16 a.m. UTC | #3
Hi Christoph,

thanks for your review.

Short of a complete rewrite of the Zorro driver support code to be
closer to what PCI does, I don' see what can be done about the use of
Zorro IDs. I don't think such a rewrite is planned in the near future,
Geert?

I can certainly use board type enums as index into a driver data (or
feature) struct array made up from the current board config data. Adds
another level of indirection while still keeping the probe code
readable. Even allows to drop the last use of these long zorro_id
macros in the probe function, and that's a clear win.
I just wouldn't want to revert to patching up bits of config data
based on board type later - we had arrived at the current code after
quite some review with input from Finn and Geert.

May take a while to test any changes though (my test box appears to be
on the move at present).

Cheers,

  Michael



On Mon, Apr 9, 2018 at 7:50 PM, Christoph Hellwig <hch@infradead.org> wrote:
> On Sun, Apr 08, 2018 at 02:45:32PM +1200, Michael Schmitz wrote:
>> New combined SCSI driver for all ESP based Zorro SCSI boards for
>> m68k Amiga.
>>
>> Code largely based on board specific parts of the old drivers (blz1230.c,
>> blz2060.c, cyberstorm.c, cyberstormII.c, fastlane.c which were removed
>> after the 2.6 kernel series for lack of maintenance) with contributions
>> by Tuomas Vainikka (TCQ bug tests and workaround) and Finn Thain (TCQ
>> bugfix by use of PIO in extended message in transfer).
>>
>> New Kconfig option and Makefile entries for new Amiga Zorro ESP SCSI
>> driver included in this patch.
>>
>> Use DMA transfers wherever possible, with board-specific DMA set-up
>> functions copied from the old driver code. Three byte reselection messages
>> do appear to cause DMA timeouts. So wire up a PIO transfer routine for
>> these instead. esp_reselect_with_tag explicitly sets esp->cmd_block_dma as
>> target address for the message bytes but PIO requires a virtual address.
>> Substiute kernel virtual address esp->cmd_block in PIO transfer call if
>> DMA address is esp->cmd_block_dma and phase is message in.
>>
>> PIO code taken from mac_esp.c where the reselection timeout issue was
>> debugged and fixed first, with minor macro and function rename.
>>
>> Signed-off-by: Michael Schmitz <schmitzmic@gmail.com>
>> Reviewed-by: Finn Thain <fthain@telegraphics.com.au>
>>
>> ---
>>
>> Changes since v1:
>>
>> Fixed issues raised by Finn Thain in initial code review:
>>
>> - use KBUILD_MODNAME for driver name string.
>> - use pr_fmt() for pr_* format prefix.
>> - clean up DMA error reporting: clear error flag before each DMA
>>   operation, set error flag on PIO error. Don't test phase in dma_err hook.
>> - change confusing comment about semantics of read flag, add comments
>>   indicating DMA direction to DMA setup hooks.
>> - drop spurious braces around switch clauses.
>> - lift cfreq setting out of ID switch clauses.
>> - fix indentation.
>> - fix error codes on probe fail.
>> - drop check for board ID when unmapping DMA regs in error handling:
>>   the ioaddr > 0xffffff test already catches all cases where the DMA
>>   registers were ioremapped.
>> - dynamically alloc zorro_private_data.
>> - fix use of driver_data field (don't mix host and zorro_esp_priv
>>   pointers). Note: require esp pointer in zorro_esp_priv to find host
>>   pointer!
>> - back out phase bits changes to pio_cmd !write branch introduced
>>   to cope with ESP SELAS command. We don't use that code so keep
>>   it in sync with Finn's version.
>> - use esp_ops.dma_length_limit() to limit transfer size. After review
>>   of old driver code, use 0xffffff max transfer size throughout.
>>
>> Fixed issues raised by Geert Uytterhoven:
>>
>> - dynamically alloc zorro_private_data, store as device drvdata.
>> - store ctrl_data for CyberStormI in driver private data.
>> - use dma_sync_single_for_device() instead of cache_push/clear.
>> - handle case of duplicate board identity - check whether board is
>>   Zorro III or Zorro II (use ROM resource data for this). Also fix
>>   up DMA mask for Zorro II boards to 32 bits (these are really CPU
>>   expansion slot boards).
>> - remove zorro3 field from driver_data struct (now in private data).
>> - add braces around ambiguous if - else construct.
>> - use named structs instead of array for board config data.
>> - use scsi_option driver data flag for boards with optional ESP.
>>
>> Other improvements and bugfixes
>>
>> - fix Zorro device table error (duplicate ID used, also raised
>>   by Kars de Jong).
>> - error code fixup in error handling path.
>> - add separate DMA setup for Blizzard 1230 II board.
>> - add support for Cyberstorm II board.
>> - add register structs and DMA setup for Zorro III Fastlane board,
>>   following logic from old fastlane.c driver. Wire up Fastlane DMA
>>   and interrupt status routines, map the necessary low 24 bit board
>>   address space used for DMA target address setting. Clean up DMA
>>   register space ioremap() branch for Zorro III boards (currently
>>   Fastlane only) to end confusion about what to do in error recovery.
>> - use esp_ops.fastlane_esp_dma_invalidate() on Fastlane (and skip
>>   fastlane_esp_reset_dma() in DMA setup).
>> - credit Tuomas Vainikka for contributing Blizzard 1230 code (and
>>   testing).
>> - clarify comment about unsupported Oktagon SCSI board.
>> - remove unused const definitions carried over from old driver.
>>
>> Changes since v2:
>>
>> - add SPDX-License-Identifier.
>> - remove unused ratelimit.h.
>> - drop phys_to_virt() in PIO transfer routine, after ensuring PIO is only
>>   used for message in transfers to esp->command_block. This obviates any
>>   need for finding the virtual address corresponding to a DMA handle.
>> - drop BUG_ON(!(cmd & ESP_CMD_DMA)) assertion in DMA setup. Short of changes
>>   to the core ESP driver, this can never trigger.
>> - make ioremap() of DMA address range conditional on zep->zorro3 and use
>>   that same condition to unmap in error handling and driver exit.
>>   Omit board ID test as we only support a single Zorro III board, and add
>>   comment on what to do when adding support for more boards.
>> - free driver private data in driver exit.
>> - various whitespace related cleanup.
>>
>> Changes since v3:
>>
>> Finn  Thain:
>> - substitute esp->command_block for transfer address in each board DMA
>>   set-up, instead of in PIO transfer function.
>> - use kzalloc for struct zorro_esp_priv.
>> - clarify comment regarding selecting between Blizzard 1230 II or
>>   board (both share the ID with the Fastlane board).
>> - use dev_get|set_drvdata instead of zorro_get|set_drvdata wrapper.
>> - remove redundant comments.
>>
>> Geert Uytterhoeven:
>> - use readb()/writeb() to access DMA registers, obviating the need for
>>   declaring register structs volatile.
>> - use const for board config and driver data table.
>> - drop ZORRO_ESP_GET_PRIV macro.
>> - add comments to clarify use of addr and fifo variables in PIO macros.
>> - add braces to Zorro II branch (DMA mask fixup).
>> - define board ops irq_pending, dma_invalidate and send_dma_cmd via
>>   function pointers in driver data.
>>
>> Tuomas Vainikka:
>> - fix wrong config description in Kconfig (from NCR7xx driver).
>>
>> Changes since v4:
>>
>> - change tag line
>>
>> Kars de Jong:
>> - fix misspelling of Blizzard 1230 as 1320 in config description
>>
>> Changes since v5:
>>
>> Christoph Hellwig:
>> - fix comment style
>> - drop initialization to zero in driver data init
>> - fix alignment in struct declarations
>> - drop braces around asm macros
>> - change board_base type to void __iomem *
>> - drop unneeded void __iomem * cast from ZTWO_VADDR() use
>> - add comment to explain why ZTWO_VADDR() use is safe
>> - move board specific functions to per-board esp_ops
>>
>> Changes since v6:
>>
>> Finn Thain:
>> - use z_writel to avoid sparse warnings in Fastlane DMA functions
>>
>> ---
>>  drivers/scsi/Kconfig     |   14 +
>>  drivers/scsi/Makefile    |    1 +
>>  drivers/scsi/zorro_esp.c | 1166 ++++++++++++++++++++++++++++++++++++++++++++++
>>  3 files changed, 1181 insertions(+), 0 deletions(-)
>>  create mode 100644 drivers/scsi/zorro_esp.c
>>
>> diff --git a/drivers/scsi/Kconfig b/drivers/scsi/Kconfig
>> index 8a739b7..94eb3f3 100644
>> --- a/drivers/scsi/Kconfig
>> +++ b/drivers/scsi/Kconfig
>> @@ -1462,6 +1462,20 @@ config SCSI_ZORRO7XX
>>             accelerator card for the Amiga 1200,
>>           - the SCSI controller on the GVP Turbo 040/060 accelerator.
>>
>> +config SCSI_ZORRO_ESP
>> +     tristate "Zorro ESP SCSI support"
>> +     depends on ZORRO && SCSI
>> +     select SCSI_SPI_ATTRS
>> +     help
>> +       Support for various NCR53C9x (ESP) based SCSI controllers on Zorro
>> +       expansion boards for the Amiga.
>> +       This includes:
>> +         - the Phase5 Blizzard 1230 II and IV SCSI controllers,
>> +         - the Phase5 Blizzard 2060 SCSI controller,
>> +         - the Phase5 Blizzard Cyberstorm and Cyberstorm II SCSI
>> +           controllers,
>> +         - the Fastlane Zorro III SCSI controller.
>> +
>>  config ATARI_SCSI
>>       tristate "Atari native SCSI support"
>>       depends on ATARI && SCSI
>> diff --git a/drivers/scsi/Makefile b/drivers/scsi/Makefile
>> index de1b3fc..20992d7 100644
>> --- a/drivers/scsi/Makefile
>> +++ b/drivers/scsi/Makefile
>> @@ -48,6 +48,7 @@ obj-$(CONFIG_INFINIBAND_ISER)       += libiscsi.o
>>  obj-$(CONFIG_ISCSI_BOOT_SYSFS)       += iscsi_boot_sysfs.o
>>  obj-$(CONFIG_SCSI_A4000T)    += 53c700.o     a4000t.o
>>  obj-$(CONFIG_SCSI_ZORRO7XX)  += 53c700.o     zorro7xx.o
>> +obj-$(CONFIG_SCSI_ZORRO_ESP) += esp_scsi.o   zorro_esp.o
>>  obj-$(CONFIG_A3000_SCSI)     += a3000.o      wd33c93.o
>>  obj-$(CONFIG_A2091_SCSI)     += a2091.o      wd33c93.o
>>  obj-$(CONFIG_GVP11_SCSI)     += gvp11.o      wd33c93.o
>> diff --git a/drivers/scsi/zorro_esp.c b/drivers/scsi/zorro_esp.c
>> new file mode 100644
>> index 0000000..9fae980
>> --- /dev/null
>> +++ b/drivers/scsi/zorro_esp.c
>> @@ -0,0 +1,1166 @@
>> +// SPDX-License-Identifier: GPL-2.0
>> +/*
>> + * zorro_esp.c: ESP front-end for Amiga ZORRO SCSI systems.
>
> We usually avoid mentioning the file name of the actual file in
> comments.
>
>> +     {
>> +             .id = ZORRO_PROD_PHASE5_BLIZZARD_1230_II_FASTLANE_Z3_CYBERSCSI_CYBERSTORM060,
>
> In PCI Land we've usually stopped using PCI IDs unless they are used
> in multiple
>
>> +             .driver_data = (unsigned long)&blizzard1230II_data,
>
> What most (or at least many) drivers do in PCI land is to just use
> an enum of types in the driver_Data field and use that as an index for
> for decisions later.  It seems like that might be the cleaner method
> here as well.
>
> Except for these nitpicks this looks great to me:
>
> Reviewed-by: Christoph Hellwig <hch@lst.de>
>
Geert Uytterhoeven April 10, 2018, 8:18 a.m. UTC | #4
Hi Michael,

On Tue, Apr 10, 2018 at 4:16 AM, Michael Schmitz <schmitzmic@gmail.com> wrote:
> On Mon, Apr 9, 2018 at 7:50 PM, Christoph Hellwig <hch@infradead.org> wrote:
>> On Sun, Apr 08, 2018 at 02:45:32PM +1200, Michael Schmitz wrote:
>>> New combined SCSI driver for all ESP based Zorro SCSI boards for
>>> m68k Amiga.
>>> +     {
>>> +             .id = ZORRO_PROD_PHASE5_BLIZZARD_1230_II_FASTLANE_Z3_CYBERSCSI_CYBERSTORM060,
>>
>> In PCI Land we've usually stopped using PCI IDs unless they are used
>> in multiple

(missing "places"?)

> Short of a complete rewrite of the Zorro driver support code to be
> closer to what PCI does, I don' see what can be done about the use of
> Zorro IDs. I don't think such a rewrite is planned in the near future,
> Geert?

I think what Christoph means is the use of the define
ZORRO_PROD_PHASE5_BLIZZARD_1230_II_FASTLANE_Z3_CYBERSCSI_CYBERSTORM060
versus hardcoded numbers, or ZORRO_ID(PHASE5, 0x0B, 0).

We have a long list of ZORRO_PROD_* definitions in
include/uapi/linux/zorro_ids.h because of historical reasons.  The list
isn't really changing (no new IDs in git history) due to almost no new
Zorro boards being made, unlike for PCI, where keeping an in-kernel list
is a lot of work, and not desirable.

Gr{oetje,eeting}s,

                        Geert
Michael Schmitz April 10, 2018, 9:50 p.m. UTC | #5
Hi Geert,

now I see, thanks.

I could change the device table to use ZORRO_ID(PHASE5, ...) style IDs
instead of the longish defines if you're OK with that.

The other changes have passed tests and I'd otherwise just send what I
have now, adding Christoph's Reviewed-by.

Cheers,

  Michael


On Tue, Apr 10, 2018 at 8:18 PM, Geert Uytterhoeven
<geert@linux-m68k.org> wrote:
> Hi Michael,
>
> On Tue, Apr 10, 2018 at 4:16 AM, Michael Schmitz <schmitzmic@gmail.com> wrote:
>> On Mon, Apr 9, 2018 at 7:50 PM, Christoph Hellwig <hch@infradead.org> wrote:
>>> On Sun, Apr 08, 2018 at 02:45:32PM +1200, Michael Schmitz wrote:
>>>> New combined SCSI driver for all ESP based Zorro SCSI boards for
>>>> m68k Amiga.
>>>> +     {
>>>> +             .id = ZORRO_PROD_PHASE5_BLIZZARD_1230_II_FASTLANE_Z3_CYBERSCSI_CYBERSTORM060,
>>>
>>> In PCI Land we've usually stopped using PCI IDs unless they are used
>>> in multiple
>
> (missing "places"?)
>
>> Short of a complete rewrite of the Zorro driver support code to be
>> closer to what PCI does, I don' see what can be done about the use of
>> Zorro IDs. I don't think such a rewrite is planned in the near future,
>> Geert?
>
> I think what Christoph means is the use of the define
> ZORRO_PROD_PHASE5_BLIZZARD_1230_II_FASTLANE_Z3_CYBERSCSI_CYBERSTORM060
> versus hardcoded numbers, or ZORRO_ID(PHASE5, 0x0B, 0).
>
> We have a long list of ZORRO_PROD_* definitions in
> include/uapi/linux/zorro_ids.h because of historical reasons.  The list
> isn't really changing (no new IDs in git history) due to almost no new
> Zorro boards being made, unlike for PCI, where keeping an in-kernel list
> is a lot of work, and not desirable.
>
> Gr{oetje,eeting}s,
>
>                         Geert
>
> --
> Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org
>
> In personal conversations with technical people, I call myself a hacker. But
> when I'm talking to journalists I just say "programmer" or something like that.
>                                 -- Linus Torvalds
Geert Uytterhoeven April 11, 2018, 6:51 a.m. UTC | #6
Hi Michael,

On Tue, Apr 10, 2018 at 11:50 PM, Michael Schmitz <schmitzmic@gmail.com> wrote:
> On Tue, Apr 10, 2018 at 8:18 PM, Geert Uytterhoeven
> <geert@linux-m68k.org> wrote:
>> On Tue, Apr 10, 2018 at 4:16 AM, Michael Schmitz <schmitzmic@gmail.com> wrote:
>>> On Mon, Apr 9, 2018 at 7:50 PM, Christoph Hellwig <hch@infradead.org> wrote:
>>>> On Sun, Apr 08, 2018 at 02:45:32PM +1200, Michael Schmitz wrote:
>>>>> New combined SCSI driver for all ESP based Zorro SCSI boards for
>>>>> m68k Amiga.
>>>>> +     {
>>>>> +             .id = ZORRO_PROD_PHASE5_BLIZZARD_1230_II_FASTLANE_Z3_CYBERSCSI_CYBERSTORM060,
>>>>
>>>> In PCI Land we've usually stopped using PCI IDs unless they are used
>>>> in multiple
>>
>> (missing "places"?)
>>
>>> Short of a complete rewrite of the Zorro driver support code to be
>>> closer to what PCI does, I don' see what can be done about the use of
>>> Zorro IDs. I don't think such a rewrite is planned in the near future,
>>> Geert?
>>
>> I think what Christoph means is the use of the define
>> ZORRO_PROD_PHASE5_BLIZZARD_1230_II_FASTLANE_Z3_CYBERSCSI_CYBERSTORM060
>> versus hardcoded numbers, or ZORRO_ID(PHASE5, 0x0B, 0).
>>
>> We have a long list of ZORRO_PROD_* definitions in
>> include/uapi/linux/zorro_ids.h because of historical reasons.  The list
>> isn't really changing (no new IDs in git history) due to almost no new
>> Zorro boards being made, unlike for PCI, where keeping an in-kernel list
>> is a lot of work, and not desirable.
>
> now I see, thanks.
>
> I could change the device table to use ZORRO_ID(PHASE5, ...) style IDs
> instead of the longish defines if you're OK with that.

I don't have a preference. If you think it makes the driver easier to read,
go for it.

Note that we can't get rid of the longish defines anyway, as they're in a
uapi header file, so you're free to keep on using it.

Gr{oetje,eeting}s,

                        Geert
John Paul Adrian Glaubitz April 11, 2018, 7:59 a.m. UTC | #7
On 04/11/2018 08:51 AM, Geert Uytterhoeven wrote:
> I don't have a preference. If you think it makes the driver easier to read,
> go for it.

That would be cool. Would that still be in time for the 4.17 merge?

Adrian
Geert Uytterhoeven April 11, 2018, 8:03 a.m. UTC | #8
Hi Adrian,

On Wed, Apr 11, 2018 at 9:59 AM, John Paul Adrian Glaubitz
<glaubitz@physik.fu-berlin.de> wrote:
> On 04/11/2018 08:51 AM, Geert Uytterhoeven wrote:
>> I don't have a preference. If you think it makes the driver easier to
>> read,
>> go for it.
>
> That would be cool. Would that still be in time for the 4.17 merge?

Nope, as new drivers need to be in linux-next before the merge window opens.

Gr{oetje,eeting}s,

                        Geert
Christoph Hellwig April 11, 2018, 8:11 a.m. UTC | #9
On Wed, Apr 11, 2018 at 10:03:12AM +0200, Geert Uytterhoeven wrote:
> > That would be cool. Would that still be in time for the 4.17 merge?
> 
> Nope, as new drivers need to be in linux-next before the merge window opens.

I always throught that entirely new drivers were an exception to that.
Geert Uytterhoeven April 11, 2018, 8:30 a.m. UTC | #10
Hi Christoph,

On Wed, Apr 11, 2018 at 10:11 AM, Christoph Hellwig <hch@infradead.org> wrote:
> On Wed, Apr 11, 2018 at 10:03:12AM +0200, Geert Uytterhoeven wrote:
>> > That would be cool. Would that still be in time for the 4.17 merge?
>>
>> Nope, as new drivers need to be in linux-next before the merge window opens.
>
> I always throught that entirely new drivers were an exception to that.

Aren't you confusing this with the new device ID rules for stable?

It's debatable, and thus up to the maintainer...

Gr{oetje,eeting}s,

                        Geert
Michael Schmitz April 11, 2018, 8:47 a.m. UTC | #11
Hi Geert,

Am 11.04.2018 um 18:51 schrieb Geert Uytterhoeven:
> Hi Michael,
> 
> On Tue, Apr 10, 2018 at 11:50 PM, Michael Schmitz <schmitzmic@gmail.com> wrote:
>>>> Short of a complete rewrite of the Zorro driver support code to be
>>>> closer to what PCI does, I don' see what can be done about the use of
>>>> Zorro IDs. I don't think such a rewrite is planned in the near future,
>>>> Geert?
>>>
>>> I think what Christoph means is the use of the define
>>> ZORRO_PROD_PHASE5_BLIZZARD_1230_II_FASTLANE_Z3_CYBERSCSI_CYBERSTORM060
>>> versus hardcoded numbers, or ZORRO_ID(PHASE5, 0x0B, 0).
>>>
>>> We have a long list of ZORRO_PROD_* definitions in
>>> include/uapi/linux/zorro_ids.h because of historical reasons.  The list
>>> isn't really changing (no new IDs in git history) due to almost no new
>>> Zorro boards being made, unlike for PCI, where keeping an in-kernel list
>>> is a lot of work, and not desirable.
>>
>> now I see, thanks.
>>
>> I could change the device table to use ZORRO_ID(PHASE5, ...) style IDs
>> instead of the longish defines if you're OK with that.
> 
> I don't have a preference. If you think it makes the driver easier to read,
> go for it.

It does get rid of a few 'line over 80 characters' warnings from
checkpatch, and with comments in the device table describing what the
IDs mean, it isn't any less readable. Let's see ...

> Note that we can't get rid of the longish defines anyway, as they're in a
> uapi header file, so you're free to keep on using it.

I don't mind these defines remaining in the header file at all - the
only place they are now used is in the device table, and hardcoded IDs
are as good as the defines there, I think.

Have a look at the result in v8 - I can easily revert to the version
with the defines if that's the consensus, it's all in git after all.

Cheers,

	Michael
Michael Schmitz April 11, 2018, 8:55 a.m. UTC | #12
Hi Geert, Christoph,

Am 11.04.2018 um 20:30 schrieb Geert Uytterhoeven:
> Hi Christoph,
> 
> On Wed, Apr 11, 2018 at 10:11 AM, Christoph Hellwig <hch@infradead.org> wrote:
>> On Wed, Apr 11, 2018 at 10:03:12AM +0200, Geert Uytterhoeven wrote:
>>>> That would be cool. Would that still be in time for the 4.17 merge?
>>>
>>> Nope, as new drivers need to be in linux-next before the merge window opens.
>>
>> I always throught that entirely new drivers were an exception to that.
> 
> Aren't you confusing this with the new device ID rules for stable?
> 
> It's debatable, and thus up to the maintainer...

Would be nice but this has been chugging along for over four years in my
queue so I'm sure it can wait a few more weeks :-)

Cheers,

	Michael
John Paul Adrian Glaubitz April 11, 2018, 9 a.m. UTC | #13
On 04/11/2018 10:55 AM, Michael Schmitz wrote:
> Would be nice but this has been chugging along for over four years in my
> queue so I'm sure it can wait a few more weeks :-)

But the driver works very well now, so it was worth the wait ;-).
diff mbox

Patch

diff --git a/drivers/scsi/Kconfig b/drivers/scsi/Kconfig
index 8a739b7..94eb3f3 100644
--- a/drivers/scsi/Kconfig
+++ b/drivers/scsi/Kconfig
@@ -1462,6 +1462,20 @@  config SCSI_ZORRO7XX
 	      accelerator card for the Amiga 1200,
 	    - the SCSI controller on the GVP Turbo 040/060 accelerator.
 
+config SCSI_ZORRO_ESP
+	tristate "Zorro ESP SCSI support"
+	depends on ZORRO && SCSI
+	select SCSI_SPI_ATTRS
+	help
+	  Support for various NCR53C9x (ESP) based SCSI controllers on Zorro
+	  expansion boards for the Amiga.
+	  This includes:
+	    - the Phase5 Blizzard 1230 II and IV SCSI controllers,
+	    - the Phase5 Blizzard 2060 SCSI controller,
+	    - the Phase5 Blizzard Cyberstorm and Cyberstorm II SCSI
+	      controllers,
+	    - the Fastlane Zorro III SCSI controller.
+
 config ATARI_SCSI
 	tristate "Atari native SCSI support"
 	depends on ATARI && SCSI
diff --git a/drivers/scsi/Makefile b/drivers/scsi/Makefile
index de1b3fc..20992d7 100644
--- a/drivers/scsi/Makefile
+++ b/drivers/scsi/Makefile
@@ -48,6 +48,7 @@  obj-$(CONFIG_INFINIBAND_ISER) 	+= libiscsi.o
 obj-$(CONFIG_ISCSI_BOOT_SYSFS)	+= iscsi_boot_sysfs.o
 obj-$(CONFIG_SCSI_A4000T)	+= 53c700.o	a4000t.o
 obj-$(CONFIG_SCSI_ZORRO7XX)	+= 53c700.o	zorro7xx.o
+obj-$(CONFIG_SCSI_ZORRO_ESP)	+= esp_scsi.o	zorro_esp.o
 obj-$(CONFIG_A3000_SCSI)	+= a3000.o	wd33c93.o
 obj-$(CONFIG_A2091_SCSI)	+= a2091.o	wd33c93.o
 obj-$(CONFIG_GVP11_SCSI)	+= gvp11.o	wd33c93.o
diff --git a/drivers/scsi/zorro_esp.c b/drivers/scsi/zorro_esp.c
new file mode 100644
index 0000000..9fae980
--- /dev/null
+++ b/drivers/scsi/zorro_esp.c
@@ -0,0 +1,1166 @@ 
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * zorro_esp.c: ESP front-end for Amiga ZORRO SCSI systems.
+ *
+ * Copyright (C) 1996 Jesper Skov (jskov@cygnus.co.uk)
+ *
+ * Copyright (C) 2011,2018 Michael Schmitz (schmitz@debian.org) for
+ *               migration to ESP SCSI core
+ *
+ * Copyright (C) 2013 Tuomas Vainikka (tuomas.vainikka@aalto.fi) for
+ *               Blizzard 1230 DMA and probe function fixes
+ *
+ * Copyright (C) 2017 Finn Thain for PIO code from Mac ESP driver adapted here
+ */
+/*
+ * ZORRO bus code from:
+ */
+/*
+ * Detection routine for the NCR53c710 based Amiga SCSI Controllers for Linux.
+ *		Amiga MacroSystemUS WarpEngine SCSI controller.
+ *		Amiga Technologies/DKB A4091 SCSI controller.
+ *
+ * Written 1997 by Alan Hourihane <alanh@fairlite.demon.co.uk>
+ * plus modifications of the 53c7xx.c driver to support the Amiga.
+ *
+ * Rewritten to use 53c700.c by Kars de Jong <jongk@linux-m68k.org>
+ */
+
+#define pr_fmt(fmt)        KBUILD_MODNAME ": " fmt
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/dma-mapping.h>
+#include <linux/scatterlist.h>
+#include <linux/delay.h>
+#include <linux/zorro.h>
+#include <linux/slab.h>
+
+#include <asm/page.h>
+#include <asm/pgtable.h>
+#include <asm/cacheflush.h>
+#include <asm/amigahw.h>
+#include <asm/amigaints.h>
+
+#include <scsi/scsi_host.h>
+#include <scsi/scsi_transport_spi.h>
+#include <scsi/scsi_device.h>
+#include <scsi/scsi_tcq.h>
+
+#include "esp_scsi.h"
+
+MODULE_AUTHOR("Michael Schmitz <schmitz@debian.org>");
+MODULE_DESCRIPTION("Amiga Zorro NCR5C9x (ESP) driver");
+MODULE_LICENSE("GPL");
+
+/* per-board register layout definitions */
+
+/* Blizzard 1230 DMA interface */
+
+struct blz1230_dma_registers {
+	unsigned char dma_addr;		/* DMA address      [0x0000] */
+	unsigned char dmapad2[0x7fff];
+	unsigned char dma_latch;	/* DMA latch        [0x8000] */
+};
+
+/* Blizzard 1230II DMA interface */
+
+struct blz1230II_dma_registers {
+	unsigned char dma_addr;		/* DMA address      [0x0000] */
+	unsigned char dmapad2[0xf];
+	unsigned char dma_latch;	/* DMA latch        [0x0010] */
+};
+
+/* Blizzard 2060 DMA interface */
+
+struct blz2060_dma_registers {
+	unsigned char dma_led_ctrl;	/* DMA led control   [0x000] */
+	unsigned char dmapad1[0x0f];
+	unsigned char dma_addr0;	/* DMA address (MSB) [0x010] */
+	unsigned char dmapad2[0x03];
+	unsigned char dma_addr1;	/* DMA address       [0x014] */
+	unsigned char dmapad3[0x03];
+	unsigned char dma_addr2;	/* DMA address       [0x018] */
+	unsigned char dmapad4[0x03];
+	unsigned char dma_addr3;	/* DMA address (LSB) [0x01c] */
+};
+
+/* DMA control bits */
+#define DMA_WRITE 0x80000000
+
+/* Cyberstorm DMA interface */
+
+struct cyber_dma_registers {
+	unsigned char dma_addr0;	/* DMA address (MSB) [0x000] */
+	unsigned char dmapad1[1];
+	unsigned char dma_addr1;	/* DMA address       [0x002] */
+	unsigned char dmapad2[1];
+	unsigned char dma_addr2;	/* DMA address       [0x004] */
+	unsigned char dmapad3[1];
+	unsigned char dma_addr3;	/* DMA address (LSB) [0x006] */
+	unsigned char dmapad4[0x3fb];
+	unsigned char cond_reg;		/* DMA cond    (ro)  [0x402] */
+#define ctrl_reg  cond_reg		/* DMA control (wo)  [0x402] */
+};
+
+/* DMA control bits */
+#define CYBER_DMA_WRITE  0x40	/* DMA direction. 1 = write */
+#define CYBER_DMA_Z3     0x20	/* 16 (Z2) or 32 (CHIP/Z3) bit DMA transfer */
+
+/* DMA status bits */
+#define CYBER_DMA_HNDL_INTR 0x80	/* DMA IRQ pending? */
+
+/* The CyberStorm II DMA interface */
+struct cyberII_dma_registers {
+	unsigned char cond_reg;		/* DMA cond    (ro)  [0x000] */
+#define ctrl_reg  cond_reg		/* DMA control (wo)  [0x000] */
+	unsigned char dmapad4[0x3f];
+	unsigned char dma_addr0;	/* DMA address (MSB) [0x040] */
+	unsigned char dmapad1[3];
+	unsigned char dma_addr1;	/* DMA address       [0x044] */
+	unsigned char dmapad2[3];
+	unsigned char dma_addr2;	/* DMA address       [0x048] */
+	unsigned char dmapad3[3];
+	unsigned char dma_addr3;	/* DMA address (LSB) [0x04c] */
+};
+
+/* Fastlane DMA interface */
+
+struct fastlane_dma_registers {
+	unsigned char cond_reg;		/* DMA status  (ro) [0x0000] */
+#define ctrl_reg  cond_reg		/* DMA control (wo) [0x0000] */
+	char dmapad1[0x3f];
+	unsigned char clear_strobe;	/* DMA clear   (wo) [0x0040] */
+};
+
+/*
+ * The controller registers can be found in the Z2 config area at these
+ * offsets:
+ */
+#define FASTLANE_ESP_ADDR	0x1000001
+
+/* DMA status bits */
+#define FASTLANE_DMA_MINT	0x80
+#define FASTLANE_DMA_IACT	0x40
+#define FASTLANE_DMA_CREQ	0x20
+
+/* DMA control bits */
+#define FASTLANE_DMA_FCODE	0xa0
+#define FASTLANE_DMA_MASK	0xf3
+#define FASTLANE_DMA_WRITE	0x08	/* 1 = write */
+#define FASTLANE_DMA_ENABLE	0x04	/* Enable DMA */
+#define FASTLANE_DMA_EDI	0x02	/* Enable DMA IRQ ? */
+#define FASTLANE_DMA_ESI	0x01	/* Enable SCSI IRQ */
+
+/*
+ * private data used for driver
+ */
+struct zorro_esp_priv {
+	struct esp *esp;		/* our ESP instance - for Scsi_host* */
+	void __iomem *board_base;	/* virtual address (Zorro III board) */
+	int error;			/* PIO error flag */
+	int zorro3;			/* board is Zorro III */
+	unsigned char ctrl_data;	/* shadow copy of ctrl_reg */
+};
+
+/*
+ * On all implementations except for the Oktagon, padding between ESP
+ * registers is three bytes.
+ * On Oktagon, it is one byte - use a different accessor there.
+ *
+ * Oktagon needs PDMA - currently unsupported!
+ */
+
+static void zorro_esp_write8(struct esp *esp, u8 val, unsigned long reg)
+{
+	writeb(val, esp->regs + (reg * 4UL));
+}
+
+static u8 zorro_esp_read8(struct esp *esp, unsigned long reg)
+{
+	return readb(esp->regs + (reg * 4UL));
+}
+
+static dma_addr_t zorro_esp_map_single(struct esp *esp, void *buf,
+				      size_t sz, int dir)
+{
+	return dma_map_single(esp->dev, buf, sz, dir);
+}
+
+static int zorro_esp_map_sg(struct esp *esp, struct scatterlist *sg,
+				  int num_sg, int dir)
+{
+	return dma_map_sg(esp->dev, sg, num_sg, dir);
+}
+
+static void zorro_esp_unmap_single(struct esp *esp, dma_addr_t addr,
+				  size_t sz, int dir)
+{
+	dma_unmap_single(esp->dev, addr, sz, dir);
+}
+
+static void zorro_esp_unmap_sg(struct esp *esp, struct scatterlist *sg,
+			      int num_sg, int dir)
+{
+	dma_unmap_sg(esp->dev, sg, num_sg, dir);
+}
+
+static int zorro_esp_irq_pending(struct esp *esp)
+{
+	/* check ESP status register; DMA has no status reg. */
+	if (zorro_esp_read8(esp, ESP_STATUS) & ESP_STAT_INTR)
+		return 1;
+
+	return 0;
+}
+
+static int cyber_esp_irq_pending(struct esp *esp)
+{
+	struct cyber_dma_registers __iomem *dregs = esp->dma_regs;
+	unsigned char dma_status = readb(&dregs->cond_reg);
+
+	/* It's important to check the DMA IRQ bit in the correct way! */
+	return ((zorro_esp_read8(esp, ESP_STATUS) & ESP_STAT_INTR) &&
+		(dma_status & CYBER_DMA_HNDL_INTR));
+}
+
+static int fastlane_esp_irq_pending(struct esp *esp)
+{
+	struct fastlane_dma_registers __iomem *dregs = esp->dma_regs;
+	unsigned char dma_status;
+
+	dma_status = readb(&dregs->cond_reg);
+
+	if (dma_status & FASTLANE_DMA_IACT)
+		return 0;	/* not our IRQ */
+
+	/* Return non-zero if ESP requested IRQ */
+	return (
+	   (dma_status & FASTLANE_DMA_CREQ) &&
+	   (!(dma_status & FASTLANE_DMA_MINT)) &&
+	   (zorro_esp_read8(esp, ESP_STATUS) & ESP_STAT_INTR));
+}
+
+static u32 zorro_esp_dma_length_limit(struct esp *esp, u32 dma_addr,
+					u32 dma_len)
+{
+	return dma_len > 0xFFFFFF ? 0xFFFFFF : dma_len;
+}
+
+static void zorro_esp_reset_dma(struct esp *esp)
+{
+	/* nothing to do here */
+}
+
+static void zorro_esp_dma_drain(struct esp *esp)
+{
+	/* nothing to do here */
+}
+
+static void zorro_esp_dma_invalidate(struct esp *esp)
+{
+	/* nothing to do here */
+}
+
+static void fastlane_esp_dma_invalidate(struct esp *esp)
+{
+	struct zorro_esp_priv *zep = dev_get_drvdata(esp->dev);
+	struct fastlane_dma_registers __iomem *dregs = esp->dma_regs;
+	unsigned char *ctrl_data = &zep->ctrl_data;
+
+	*ctrl_data = (*ctrl_data & FASTLANE_DMA_MASK);
+	writeb(0, &dregs->clear_strobe);
+	z_writel(0, zep->board_base);
+}
+
+/*
+ * Programmed IO routines follow.
+ */
+
+static inline unsigned int zorro_esp_wait_for_fifo(struct esp *esp)
+{
+	int i = 500000;
+
+	do {
+		unsigned int fbytes = zorro_esp_read8(esp, ESP_FFLAGS)
+							& ESP_FF_FBYTES;
+
+		if (fbytes)
+			return fbytes;
+
+		udelay(2);
+	} while (--i);
+
+	pr_err("FIFO is empty (sreg %02x)\n",
+	       zorro_esp_read8(esp, ESP_STATUS));
+	return 0;
+}
+
+static inline int zorro_esp_wait_for_intr(struct esp *esp)
+{
+	struct zorro_esp_priv *zep = dev_get_drvdata(esp->dev);
+	int i = 500000;
+
+	do {
+		esp->sreg = zorro_esp_read8(esp, ESP_STATUS);
+		if (esp->sreg & ESP_STAT_INTR)
+			return 0;
+
+		udelay(2);
+	} while (--i);
+
+	pr_err("IRQ timeout (sreg %02x)\n", esp->sreg);
+	zep->error = 1;
+	return 1;
+}
+
+/*
+ * PIO macros as used in mac_esp.c.
+ * Note that addr and fifo arguments are local-scope variables declared
+ * in zorro_esp_send_pio_cmd(), the macros are only used in that function,
+ * and addr and fifo are referenced in each use of the macros so there
+ * is no need to pass them as macro parameters.
+ */
+#define ZORRO_ESP_PIO_LOOP(operands, reg1) \
+	asm volatile ( \
+	     "1:     moveb " operands "\n" \
+	     "       subqw #1,%1       \n" \
+	     "       jbne 1b           \n" \
+	     : "+a" (addr), "+r" (reg1) \
+	     : "a" (fifo));
+
+#define ZORRO_ESP_PIO_FILL(operands, reg1) \
+	asm volatile ( \
+	     "       moveb " operands "\n" \
+	     "       moveb " operands "\n" \
+	     "       moveb " operands "\n" \
+	     "       moveb " operands "\n" \
+	     "       moveb " operands "\n" \
+	     "       moveb " operands "\n" \
+	     "       moveb " operands "\n" \
+	     "       moveb " operands "\n" \
+	     "       moveb " operands "\n" \
+	     "       moveb " operands "\n" \
+	     "       moveb " operands "\n" \
+	     "       moveb " operands "\n" \
+	     "       moveb " operands "\n" \
+	     "       moveb " operands "\n" \
+	     "       moveb " operands "\n" \
+	     "       moveb " operands "\n" \
+	     "       subqw #8,%1       \n" \
+	     "       subqw #8,%1       \n" \
+	     : "+a" (addr), "+r" (reg1) \
+	     : "a" (fifo));
+
+#define ZORRO_ESP_FIFO_SIZE 16
+
+static void zorro_esp_send_pio_cmd(struct esp *esp, u32 addr, u32 esp_count,
+				 u32 dma_count, int write, u8 cmd)
+{
+	struct zorro_esp_priv *zep = dev_get_drvdata(esp->dev);
+	u8 __iomem *fifo = esp->regs + ESP_FDATA * 16;
+	u8 phase = esp->sreg & ESP_STAT_PMASK;
+
+	cmd &= ~ESP_CMD_DMA;
+
+	if (write) {
+		u8 *dst = (u8 *)addr;
+		u8 mask = ~(phase == ESP_MIP ? ESP_INTR_FDONE : ESP_INTR_BSERV);
+
+		scsi_esp_cmd(esp, cmd);
+
+		while (1) {
+			if (!zorro_esp_wait_for_fifo(esp))
+				break;
+
+			*dst++ = zorro_esp_read8(esp, ESP_FDATA);
+			--esp_count;
+
+			if (!esp_count)
+				break;
+
+			if (zorro_esp_wait_for_intr(esp))
+				break;
+
+			if ((esp->sreg & ESP_STAT_PMASK) != phase)
+				break;
+
+			esp->ireg = zorro_esp_read8(esp, ESP_INTRPT);
+			if (esp->ireg & mask) {
+				zep->error = 1;
+				break;
+			}
+
+			if (phase == ESP_MIP)
+				scsi_esp_cmd(esp, ESP_CMD_MOK);
+
+			scsi_esp_cmd(esp, ESP_CMD_TI);
+		}
+	} else {	/* unused, as long as we only handle MIP here */
+		scsi_esp_cmd(esp, ESP_CMD_FLUSH);
+
+		if (esp_count >= ZORRO_ESP_FIFO_SIZE)
+			ZORRO_ESP_PIO_FILL("%0@+,%2@", esp_count)
+		else
+			ZORRO_ESP_PIO_LOOP("%0@+,%2@", esp_count)
+
+		scsi_esp_cmd(esp, cmd);
+
+		while (esp_count) {
+			unsigned int n;
+
+			if (zorro_esp_wait_for_intr(esp))
+				break;
+
+			if ((esp->sreg & ESP_STAT_PMASK) != phase)
+				break;
+
+			esp->ireg = zorro_esp_read8(esp, ESP_INTRPT);
+			if (esp->ireg & ~ESP_INTR_BSERV) {
+				zep->error = 1;
+				break;
+			}
+
+			n = ZORRO_ESP_FIFO_SIZE -
+			    (zorro_esp_read8(esp, ESP_FFLAGS) & ESP_FF_FBYTES);
+			if (n > esp_count)
+				n = esp_count;
+
+			if (n == ZORRO_ESP_FIFO_SIZE)
+				ZORRO_ESP_PIO_FILL("%0@+,%2@", esp_count)
+			else {
+				esp_count -= n;
+				ZORRO_ESP_PIO_LOOP("%0@+,%2@", n)
+			}
+
+			scsi_esp_cmd(esp, ESP_CMD_TI);
+		}
+	}
+}
+
+/* Blizzard 1230/60 SCSI-IV DMA */
+
+static void zorro_esp_send_blz1230_dma_cmd(struct esp *esp, u32 addr,
+			u32 esp_count, u32 dma_count, int write, u8 cmd)
+{
+	struct zorro_esp_priv *zep = dev_get_drvdata(esp->dev);
+	struct blz1230_dma_registers __iomem *dregs = esp->dma_regs;
+	u8 phase = esp->sreg & ESP_STAT_PMASK;
+
+	zep->error = 0;
+	/*
+	 * Use PIO if transferring message bytes to esp->command_block_dma.
+	 * PIO requires a virtual address, so substitute esp->command_block
+	 * for addr.
+	 */
+	if (phase == ESP_MIP && addr == esp->command_block_dma) {
+		zorro_esp_send_pio_cmd(esp, (u32) esp->command_block,
+					esp_count, dma_count, write, cmd);
+		return;
+	}
+
+	if (write)
+		/* DMA receive */
+		dma_sync_single_for_device(esp->dev, addr, esp_count,
+				DMA_FROM_DEVICE);
+	else
+		/* DMA send */
+		dma_sync_single_for_device(esp->dev, addr, esp_count,
+				DMA_TO_DEVICE);
+
+	addr >>= 1;
+	if (write)
+		addr &= ~(DMA_WRITE);
+	else
+		addr |= DMA_WRITE;
+
+	writeb((addr >> 24) & 0xff, &dregs->dma_latch);
+	writeb((addr >> 24) & 0xff, &dregs->dma_addr);
+	writeb((addr >> 16) & 0xff, &dregs->dma_addr);
+	writeb((addr >>  8) & 0xff, &dregs->dma_addr);
+	writeb(addr & 0xff, &dregs->dma_addr);
+
+	scsi_esp_cmd(esp, ESP_CMD_DMA);
+	zorro_esp_write8(esp, (esp_count >> 0) & 0xff, ESP_TCLOW);
+	zorro_esp_write8(esp, (esp_count >> 8) & 0xff, ESP_TCMED);
+	zorro_esp_write8(esp, (esp_count >> 16) & 0xff, ESP_TCHI);
+
+	scsi_esp_cmd(esp, cmd);
+}
+
+/* Blizzard 1230-II DMA */
+
+static void zorro_esp_send_blz1230II_dma_cmd(struct esp *esp, u32 addr,
+			u32 esp_count, u32 dma_count, int write, u8 cmd)
+{
+	struct zorro_esp_priv *zep = dev_get_drvdata(esp->dev);
+	struct blz1230II_dma_registers __iomem *dregs = esp->dma_regs;
+	u8 phase = esp->sreg & ESP_STAT_PMASK;
+
+	zep->error = 0;
+	/* Use PIO if transferring message bytes to esp->command_block_dma */
+	if (phase == ESP_MIP && addr == esp->command_block_dma) {
+		zorro_esp_send_pio_cmd(esp, (u32) esp->command_block,
+					esp_count, dma_count, write, cmd);
+		return;
+	}
+
+	if (write)
+		/* DMA receive */
+		dma_sync_single_for_device(esp->dev, addr, esp_count,
+				DMA_FROM_DEVICE);
+	else
+		/* DMA send */
+		dma_sync_single_for_device(esp->dev, addr, esp_count,
+				DMA_TO_DEVICE);
+
+	addr >>= 1;
+	if (write)
+		addr &= ~(DMA_WRITE);
+	else
+		addr |= DMA_WRITE;
+
+	writeb((addr >> 24) & 0xff, &dregs->dma_latch);
+	writeb((addr >> 16) & 0xff, &dregs->dma_addr);
+	writeb((addr >>  8) & 0xff, &dregs->dma_addr);
+	writeb(addr & 0xff, &dregs->dma_addr);
+
+	scsi_esp_cmd(esp, ESP_CMD_DMA);
+	zorro_esp_write8(esp, (esp_count >> 0) & 0xff, ESP_TCLOW);
+	zorro_esp_write8(esp, (esp_count >> 8) & 0xff, ESP_TCMED);
+	zorro_esp_write8(esp, (esp_count >> 16) & 0xff, ESP_TCHI);
+
+	scsi_esp_cmd(esp, cmd);
+}
+
+/* Blizzard 2060 DMA */
+
+static void zorro_esp_send_blz2060_dma_cmd(struct esp *esp, u32 addr,
+			u32 esp_count, u32 dma_count, int write, u8 cmd)
+{
+	struct zorro_esp_priv *zep = dev_get_drvdata(esp->dev);
+	struct blz2060_dma_registers __iomem *dregs = esp->dma_regs;
+	u8 phase = esp->sreg & ESP_STAT_PMASK;
+
+	zep->error = 0;
+	/* Use PIO if transferring message bytes to esp->command_block_dma */
+	if (phase == ESP_MIP && addr == esp->command_block_dma) {
+		zorro_esp_send_pio_cmd(esp, (u32) esp->command_block,
+					esp_count, dma_count, write, cmd);
+		return;
+	}
+
+	if (write)
+		/* DMA receive */
+		dma_sync_single_for_device(esp->dev, addr, esp_count,
+				DMA_FROM_DEVICE);
+	else
+		/* DMA send */
+		dma_sync_single_for_device(esp->dev, addr, esp_count,
+				DMA_TO_DEVICE);
+
+	addr >>= 1;
+	if (write)
+		addr &= ~(DMA_WRITE);
+	else
+		addr |= DMA_WRITE;
+
+	writeb(addr & 0xff, &dregs->dma_addr3);
+	writeb((addr >>  8) & 0xff, &dregs->dma_addr2);
+	writeb((addr >> 16) & 0xff, &dregs->dma_addr1);
+	writeb((addr >> 24) & 0xff, &dregs->dma_addr0);
+
+	scsi_esp_cmd(esp, ESP_CMD_DMA);
+	zorro_esp_write8(esp, (esp_count >> 0) & 0xff, ESP_TCLOW);
+	zorro_esp_write8(esp, (esp_count >> 8) & 0xff, ESP_TCMED);
+	zorro_esp_write8(esp, (esp_count >> 16) & 0xff, ESP_TCHI);
+
+	scsi_esp_cmd(esp, cmd);
+}
+
+/* Cyberstorm I DMA */
+
+static void zorro_esp_send_cyber_dma_cmd(struct esp *esp, u32 addr,
+			u32 esp_count, u32 dma_count, int write, u8 cmd)
+{
+	struct zorro_esp_priv *zep = dev_get_drvdata(esp->dev);
+	struct cyber_dma_registers __iomem *dregs = esp->dma_regs;
+	u8 phase = esp->sreg & ESP_STAT_PMASK;
+	unsigned char *ctrl_data = &zep->ctrl_data;
+
+	zep->error = 0;
+	/* Use PIO if transferring message bytes to esp->command_block_dma */
+	if (phase == ESP_MIP && addr == esp->command_block_dma) {
+		zorro_esp_send_pio_cmd(esp, (u32) esp->command_block,
+					esp_count, dma_count, write, cmd);
+		return;
+	}
+
+	zorro_esp_write8(esp, (esp_count >> 0) & 0xff, ESP_TCLOW);
+	zorro_esp_write8(esp, (esp_count >> 8) & 0xff, ESP_TCMED);
+	zorro_esp_write8(esp, (esp_count >> 16) & 0xff, ESP_TCHI);
+
+	if (write) {
+		/* DMA receive */
+		dma_sync_single_for_device(esp->dev, addr, esp_count,
+				DMA_FROM_DEVICE);
+		addr &= ~(1);
+	} else {
+		/* DMA send */
+		dma_sync_single_for_device(esp->dev, addr, esp_count,
+				DMA_TO_DEVICE);
+		addr |= 1;
+	}
+
+	writeb((addr >> 24) & 0xff, &dregs->dma_addr0);
+	writeb((addr >> 16) & 0xff, &dregs->dma_addr1);
+	writeb((addr >>  8) & 0xff, &dregs->dma_addr2);
+	writeb(addr & 0xff, &dregs->dma_addr3);
+
+	if (write)
+		*ctrl_data &= ~(CYBER_DMA_WRITE);
+	else
+		*ctrl_data |= CYBER_DMA_WRITE;
+
+	*ctrl_data &= ~(CYBER_DMA_Z3);	/* Z2, do 16 bit DMA */
+
+	writeb(*ctrl_data, &dregs->ctrl_reg);
+
+	scsi_esp_cmd(esp, cmd);
+}
+
+/* Cyberstorm II DMA */
+
+static void zorro_esp_send_cyberII_dma_cmd(struct esp *esp, u32 addr,
+			u32 esp_count, u32 dma_count, int write, u8 cmd)
+{
+	struct zorro_esp_priv *zep = dev_get_drvdata(esp->dev);
+	struct cyberII_dma_registers __iomem *dregs = esp->dma_regs;
+	u8 phase = esp->sreg & ESP_STAT_PMASK;
+
+	zep->error = 0;
+	/* Use PIO if transferring message bytes to esp->command_block_dma */
+	if (phase == ESP_MIP && addr == esp->command_block_dma) {
+		zorro_esp_send_pio_cmd(esp, (u32) esp->command_block,
+					esp_count, dma_count, write, cmd);
+		return;
+	}
+
+	zorro_esp_write8(esp, (esp_count >> 0) & 0xff, ESP_TCLOW);
+	zorro_esp_write8(esp, (esp_count >> 8) & 0xff, ESP_TCMED);
+	zorro_esp_write8(esp, (esp_count >> 16) & 0xff, ESP_TCHI);
+
+	if (write) {
+		/* DMA receive */
+		dma_sync_single_for_device(esp->dev, addr, esp_count,
+				DMA_FROM_DEVICE);
+		addr &= ~(1);
+	} else {
+		/* DMA send */
+		dma_sync_single_for_device(esp->dev, addr, esp_count,
+				DMA_TO_DEVICE);
+		addr |= 1;
+	}
+
+	writeb((addr >> 24) & 0xff, &dregs->dma_addr0);
+	writeb((addr >> 16) & 0xff, &dregs->dma_addr1);
+	writeb((addr >>  8) & 0xff, &dregs->dma_addr2);
+	writeb(addr & 0xff, &dregs->dma_addr3);
+
+	scsi_esp_cmd(esp, cmd);
+}
+
+/* Fastlane DMA */
+
+static void zorro_esp_send_fastlane_dma_cmd(struct esp *esp, u32 addr,
+			u32 esp_count, u32 dma_count, int write, u8 cmd)
+{
+	struct zorro_esp_priv *zep = dev_get_drvdata(esp->dev);
+	struct fastlane_dma_registers __iomem *dregs = esp->dma_regs;
+	u8 phase = esp->sreg & ESP_STAT_PMASK;
+	unsigned char *ctrl_data = &zep->ctrl_data;
+
+	zep->error = 0;
+	/* Use PIO if transferring message bytes to esp->command_block_dma */
+	if (phase == ESP_MIP && addr == esp->command_block_dma) {
+		zorro_esp_send_pio_cmd(esp, (u32) esp->command_block,
+					esp_count, dma_count, write, cmd);
+		return;
+	}
+
+	zorro_esp_write8(esp, (esp_count >> 0) & 0xff, ESP_TCLOW);
+	zorro_esp_write8(esp, (esp_count >> 8) & 0xff, ESP_TCMED);
+	zorro_esp_write8(esp, (esp_count >> 16) & 0xff, ESP_TCHI);
+
+	if (write) {
+		/* DMA receive */
+		dma_sync_single_for_device(esp->dev, addr, esp_count,
+				DMA_FROM_DEVICE);
+		addr &= ~(1);
+	} else {
+		/* DMA send */
+		dma_sync_single_for_device(esp->dev, addr, esp_count,
+				DMA_TO_DEVICE);
+		addr |= 1;
+	}
+
+	writeb(0, &dregs->clear_strobe);
+	z_writel(addr, ((addr & 0x00ffffff) + zep->board_base));
+
+	if (write) {
+		*ctrl_data = (*ctrl_data & FASTLANE_DMA_MASK) |
+				FASTLANE_DMA_ENABLE;
+	} else {
+		*ctrl_data = ((*ctrl_data & FASTLANE_DMA_MASK) |
+				FASTLANE_DMA_ENABLE |
+				FASTLANE_DMA_WRITE);
+	}
+
+	writeb(*ctrl_data, &dregs->ctrl_reg);
+
+	scsi_esp_cmd(esp, cmd);
+}
+
+static int zorro_esp_dma_error(struct esp *esp)
+{
+	struct zorro_esp_priv *zep = dev_get_drvdata(esp->dev);
+
+	/* check for error in case we've been doing PIO */
+	if (zep->error == 1)
+		return 1;
+
+	/* do nothing - there seems to be no way to check for DMA errors */
+	return 0;
+}
+
+/* per-board ESP driver ops */
+
+static const struct esp_driver_ops blz1230_esp_ops = {
+	.esp_write8		= zorro_esp_write8,
+	.esp_read8		= zorro_esp_read8,
+	.map_single		= zorro_esp_map_single,
+	.map_sg			= zorro_esp_map_sg,
+	.unmap_single		= zorro_esp_unmap_single,
+	.unmap_sg		= zorro_esp_unmap_sg,
+	.irq_pending		= zorro_esp_irq_pending,
+	.dma_length_limit	= zorro_esp_dma_length_limit,
+	.reset_dma		= zorro_esp_reset_dma,
+	.dma_drain		= zorro_esp_dma_drain,
+	.dma_invalidate		= zorro_esp_dma_invalidate,
+	.send_dma_cmd		= zorro_esp_send_blz1230_dma_cmd,
+	.dma_error		= zorro_esp_dma_error,
+};
+
+static const struct esp_driver_ops blz1230II_esp_ops = {
+	.esp_write8		= zorro_esp_write8,
+	.esp_read8		= zorro_esp_read8,
+	.map_single		= zorro_esp_map_single,
+	.map_sg			= zorro_esp_map_sg,
+	.unmap_single		= zorro_esp_unmap_single,
+	.unmap_sg		= zorro_esp_unmap_sg,
+	.irq_pending		= zorro_esp_irq_pending,
+	.dma_length_limit	= zorro_esp_dma_length_limit,
+	.reset_dma		= zorro_esp_reset_dma,
+	.dma_drain		= zorro_esp_dma_drain,
+	.dma_invalidate		= zorro_esp_dma_invalidate,
+	.send_dma_cmd		= zorro_esp_send_blz1230II_dma_cmd,
+	.dma_error		= zorro_esp_dma_error,
+};
+
+static const struct esp_driver_ops blz2060_esp_ops = {
+	.esp_write8		= zorro_esp_write8,
+	.esp_read8		= zorro_esp_read8,
+	.map_single		= zorro_esp_map_single,
+	.map_sg			= zorro_esp_map_sg,
+	.unmap_single		= zorro_esp_unmap_single,
+	.unmap_sg		= zorro_esp_unmap_sg,
+	.irq_pending		= zorro_esp_irq_pending,
+	.dma_length_limit	= zorro_esp_dma_length_limit,
+	.reset_dma		= zorro_esp_reset_dma,
+	.dma_drain		= zorro_esp_dma_drain,
+	.dma_invalidate		= zorro_esp_dma_invalidate,
+	.send_dma_cmd		= zorro_esp_send_blz2060_dma_cmd,
+	.dma_error		= zorro_esp_dma_error,
+};
+
+static const struct esp_driver_ops cyber_esp_ops = {
+	.esp_write8		= zorro_esp_write8,
+	.esp_read8		= zorro_esp_read8,
+	.map_single		= zorro_esp_map_single,
+	.map_sg			= zorro_esp_map_sg,
+	.unmap_single		= zorro_esp_unmap_single,
+	.unmap_sg		= zorro_esp_unmap_sg,
+	.irq_pending		= cyber_esp_irq_pending,
+	.dma_length_limit	= zorro_esp_dma_length_limit,
+	.reset_dma		= zorro_esp_reset_dma,
+	.dma_drain		= zorro_esp_dma_drain,
+	.dma_invalidate		= zorro_esp_dma_invalidate,
+	.send_dma_cmd		= zorro_esp_send_cyber_dma_cmd,
+	.dma_error		= zorro_esp_dma_error,
+};
+
+static const struct esp_driver_ops cyberII_esp_ops = {
+	.esp_write8		= zorro_esp_write8,
+	.esp_read8		= zorro_esp_read8,
+	.map_single		= zorro_esp_map_single,
+	.map_sg			= zorro_esp_map_sg,
+	.unmap_single		= zorro_esp_unmap_single,
+	.unmap_sg		= zorro_esp_unmap_sg,
+	.irq_pending		= zorro_esp_irq_pending,
+	.dma_length_limit	= zorro_esp_dma_length_limit,
+	.reset_dma		= zorro_esp_reset_dma,
+	.dma_drain		= zorro_esp_dma_drain,
+	.dma_invalidate		= zorro_esp_dma_invalidate,
+	.send_dma_cmd		= zorro_esp_send_cyberII_dma_cmd,
+	.dma_error		= zorro_esp_dma_error,
+};
+
+static const struct esp_driver_ops fastlane_esp_ops = {
+	.esp_write8		= zorro_esp_write8,
+	.esp_read8		= zorro_esp_read8,
+	.map_single		= zorro_esp_map_single,
+	.map_sg			= zorro_esp_map_sg,
+	.unmap_single		= zorro_esp_unmap_single,
+	.unmap_sg		= zorro_esp_unmap_sg,
+	.irq_pending		= fastlane_esp_irq_pending,
+	.dma_length_limit	= zorro_esp_dma_length_limit,
+	.reset_dma		= zorro_esp_reset_dma,
+	.dma_drain		= zorro_esp_dma_drain,
+	.dma_invalidate		= fastlane_esp_dma_invalidate,
+	.send_dma_cmd		= zorro_esp_send_fastlane_dma_cmd,
+	.dma_error		= zorro_esp_dma_error,
+};
+
+/* Zorro driver config data */
+
+struct zorro_driver_data {
+	const char *name;
+	unsigned long offset;
+	unsigned long dma_offset;
+	int absolute;	/* offset is absolute address */
+	int scsi_option;
+	const struct esp_driver_ops *esp_ops;
+};
+
+/* per-board config data */
+
+static const struct zorro_driver_data cyberstormI_data = {
+	.name		= "CyberStormI",
+	.offset		= 0xf400,
+	.dma_offset	= 0xf800,
+	.esp_ops	= &cyber_esp_ops,
+};
+
+static const struct zorro_driver_data cyberstormII_data = {
+	.name		= "CyberStormII",
+	.offset		= 0x1ff03,
+	.dma_offset	= 0x1ff43,
+	.scsi_option	= 1,
+	.esp_ops	= &cyberII_esp_ops,
+};
+
+static const struct zorro_driver_data blizzard2060_data = {
+	.name		= "Blizzard 2060",
+	.offset		= 0x1ff00,
+	.dma_offset	= 0x1ffe0,
+	.esp_ops	= &blz2060_esp_ops,
+};
+
+static const struct zorro_driver_data blizzard1230_data = {
+	.name		= "Blizzard 1230",
+	.offset		= 0x8000,
+	.dma_offset	= 0x10000,
+	.scsi_option	= 1,
+	.esp_ops	= &blz1230_esp_ops,
+};
+
+static const struct zorro_driver_data blizzard1230II_data = {
+	.name		= "Blizzard 1230II",
+	.offset		= 0x10000,
+	.dma_offset	= 0x10021,
+	.scsi_option	= 1,
+	.esp_ops	= &blz1230II_esp_ops,
+};
+
+static const struct zorro_driver_data fastlanez3_data = {
+	.name		= "Fastlane",
+	.offset		= 0x1000001,
+	.dma_offset	= 0x1000041,
+	.esp_ops	= &fastlane_esp_ops,
+};
+
+static const struct zorro_device_id zorro_esp_zorro_tbl[] = {
+	{
+		.id = ZORRO_PROD_PHASE5_BLIZZARD_1220_CYBERSTORM,
+		.driver_data = (unsigned long)&cyberstormI_data,
+	},
+	{
+		.id = ZORRO_PROD_PHASE5_CYBERSTORM_MK_II,
+		.driver_data = (unsigned long)&cyberstormII_data,
+	},
+	{
+		.id = ZORRO_PROD_PHASE5_BLIZZARD_2060,
+		.driver_data = (unsigned long)&blizzard2060_data,
+	},
+	{
+		.id = ZORRO_PROD_PHASE5_BLIZZARD_1230_IV_1260,
+		.driver_data = (unsigned long)&blizzard1230_data,
+	},
+	{
+		.id = ZORRO_PROD_PHASE5_BLIZZARD_1230_II_FASTLANE_Z3_CYBERSCSI_CYBERSTORM060,
+		.driver_data = (unsigned long)&blizzard1230II_data,
+	},
+	{ 0 }
+};
+MODULE_DEVICE_TABLE(zorro, zorro_esp_zorro_tbl);
+
+static int zorro_esp_probe(struct zorro_dev *z,
+				       const struct zorro_device_id *ent)
+{
+	struct scsi_host_template *tpnt = &scsi_esp_template;
+	struct Scsi_Host *host;
+	struct esp *esp;
+	const struct zorro_driver_data *zdd;
+	struct zorro_esp_priv *zep;
+	unsigned long board, ioaddr, dmaaddr;
+	int err;
+
+	board = zorro_resource_start(z);
+	zdd = (struct zorro_driver_data *)ent->driver_data;
+
+	pr_info("%s found at address 0x%lx.\n", zdd->name, board);
+
+	zep = kzalloc(sizeof(*zep), GFP_KERNEL);
+	if (!zep) {
+		pr_err("Can't allocate device private data!\n");
+		return -ENOMEM;
+	}
+
+	/* let's figure out whether we have a Zorro II or Zorro III board */
+	if ((z->rom.er_Type & ERT_TYPEMASK) == ERT_ZORROIII) {
+		if (board > 0xffffff)
+			zep->zorro3 = 1;
+	} else {
+		/*
+		 * Even though most of these boards identify as Zorro II,
+		 * they are in fact CPU expansion slot boards and have full
+		 * access to all of memory. Fix up DMA bitmask here.
+		 */
+		z->dev.coherent_dma_mask = DMA_BIT_MASK(32);
+	}
+
+	/*
+	 * If Zorro III and ID matches Fastlane, our device table entry
+	 * contains data for the Blizzard 1230 II board which does share the
+	 * same ID. Fix up device table entry here.
+	 * TODO: Some Cyberstom060 boards also share this ID but would need
+	 * to use the Cyberstorm I driver data ... we catch this by checking
+	 * for presence of ESP chip later, but don't try to fix up yet.
+	 */
+	if (zep->zorro3 && ent->id ==
+	ZORRO_PROD_PHASE5_BLIZZARD_1230_II_FASTLANE_Z3_CYBERSCSI_CYBERSTORM060) {
+		pr_info("%s at address 0x%lx is Fastlane Z3, fixing data!\n",
+			zdd->name, board);
+		zdd = &fastlanez3_data;
+	}
+
+	if (zdd->absolute) {
+		ioaddr  = zdd->offset;
+		dmaaddr = zdd->dma_offset;
+	} else {
+		ioaddr  = board + zdd->offset;
+		dmaaddr = board + zdd->dma_offset;
+	}
+
+	if (!zorro_request_device(z, zdd->name)) {
+		pr_err("cannot reserve region 0x%lx, abort\n",
+		       board);
+		err = -EBUSY;
+		goto fail_free_zep;
+	}
+
+	host = scsi_host_alloc(tpnt, sizeof(struct esp));
+
+	if (!host) {
+		pr_err("No host detected; board configuration problem?\n");
+		err = -ENOMEM;
+		goto fail_release_device;
+	}
+
+	host->base		= ioaddr;
+	host->this_id		= 7;
+
+	esp			= shost_priv(host);
+	esp->host		= host;
+	esp->dev		= &z->dev;
+
+	esp->scsi_id		= host->this_id;
+	esp->scsi_id_mask	= (1 << esp->scsi_id);
+
+	esp->cfreq = 40000000;
+
+	zep->esp = esp;
+
+	dev_set_drvdata(esp->dev, zep);
+
+	/* additional setup required for Fastlane */
+	if (zep->zorro3 && ent->id ==
+	ZORRO_PROD_PHASE5_BLIZZARD_1230_II_FASTLANE_Z3_CYBERSCSI_CYBERSTORM060) {
+		/* map full address space up to ESP base for DMA */
+		zep->board_base = ioremap_nocache(board,
+						FASTLANE_ESP_ADDR-1);
+		if (!zep->board_base) {
+			pr_err("Cannot allocate board address space\n");
+			err = -ENOMEM;
+			goto fail_free_host;
+		}
+		/* initialize DMA control shadow register */
+		zep->ctrl_data = (FASTLANE_DMA_FCODE |
+				  FASTLANE_DMA_EDI | FASTLANE_DMA_ESI);
+	}
+
+	esp->ops = zdd->esp_ops;
+
+	if (ioaddr > 0xffffff)
+		esp->regs = ioremap_nocache(ioaddr, 0x20);
+	else
+		/* ZorroII address space remapped nocache by early startup */
+		esp->regs = ZTWO_VADDR(ioaddr);
+
+	if (!esp->regs) {
+		err = -ENOMEM;
+		goto fail_unmap_fastlane;
+	}
+
+	/* Check whether a Blizzard 12x0 or CyberstormII really has SCSI */
+	if (zdd->scsi_option) {
+		zorro_esp_write8(esp, (ESP_CONFIG1_PENABLE | 7), ESP_CFG1);
+		if (zorro_esp_read8(esp, ESP_CFG1) != (ESP_CONFIG1_PENABLE|7)) {
+			err = -ENODEV;
+			goto fail_unmap_regs;
+		}
+	}
+
+	if (zep->zorro3) {
+		/*
+		 * Only Fastlane Z3 for now - add switch for correct struct
+		 * dma_registers size if adding any more
+		 */
+		esp->dma_regs = ioremap_nocache(dmaaddr,
+				sizeof(struct fastlane_dma_registers));
+	} else
+		/* ZorroII address space remapped nocache by early startup */
+		esp->dma_regs = ZTWO_VADDR(dmaaddr);
+
+	if (!esp->dma_regs) {
+		err = -ENOMEM;
+		goto fail_unmap_regs;
+	}
+
+	esp->command_block = dma_alloc_coherent(esp->dev, 16,
+						&esp->command_block_dma,
+						GFP_KERNEL);
+
+	if (!esp->command_block) {
+		err = -ENOMEM;
+		goto fail_unmap_dma_regs;
+	}
+
+	host->irq = IRQ_AMIGA_PORTS;
+	err = request_irq(host->irq, scsi_esp_intr, IRQF_SHARED,
+			  "Amiga Zorro ESP", esp);
+	if (err < 0) {
+		err = -ENODEV;
+		goto fail_free_command_block;
+	}
+
+	/* register the chip */
+	err = scsi_esp_register(esp, &z->dev);
+
+	if (err) {
+		err = -ENOMEM;
+		goto fail_free_irq;
+	}
+
+	return 0;
+
+fail_free_irq:
+	free_irq(host->irq, esp);
+
+fail_free_command_block:
+	dma_free_coherent(esp->dev, 16,
+			  esp->command_block,
+			  esp->command_block_dma);
+
+fail_unmap_dma_regs:
+	if (zep->zorro3)
+		iounmap(esp->dma_regs);
+
+fail_unmap_regs:
+	if (ioaddr > 0xffffff)
+		iounmap(esp->regs);
+
+fail_unmap_fastlane:
+	if (zep->zorro3)
+		iounmap(zep->board_base);
+
+fail_free_host:
+	scsi_host_put(host);
+
+fail_release_device:
+	zorro_release_device(z);
+
+fail_free_zep:
+	kfree(zep);
+
+	return err;
+}
+
+static void zorro_esp_remove(struct zorro_dev *z)
+{
+	struct zorro_esp_priv *zep = dev_get_drvdata(&z->dev);
+	struct esp *esp	= zep->esp;
+	struct Scsi_Host *host = esp->host;
+
+	scsi_esp_unregister(esp);
+
+	free_irq(host->irq, esp);
+	dma_free_coherent(esp->dev, 16,
+			  esp->command_block,
+			  esp->command_block_dma);
+
+	if (zep->zorro3) {
+		iounmap(zep->board_base);
+		iounmap(esp->dma_regs);
+	}
+
+	if (host->base > 0xffffff)
+		iounmap(esp->regs);
+
+	scsi_host_put(host);
+
+	zorro_release_device(z);
+
+	kfree(zep);
+}
+
+static struct zorro_driver zorro_esp_driver = {
+	.name	  = KBUILD_MODNAME,
+	.id_table = zorro_esp_zorro_tbl,
+	.probe	  = zorro_esp_probe,
+	.remove	  = zorro_esp_remove,
+};
+
+static int __init zorro_esp_scsi_init(void)
+{
+	return zorro_register_driver(&zorro_esp_driver);
+}
+
+static void __exit zorro_esp_scsi_exit(void)
+{
+	zorro_unregister_driver(&zorro_esp_driver);
+}
+
+module_init(zorro_esp_scsi_init);
+module_exit(zorro_esp_scsi_exit);