root/drivers/scsi/zorro_esp.c
// SPDX-License-Identifier: GPL-2.0
/*
 * 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
 */
/*
 * 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 <linux/pgtable.h>

#include <asm/page.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 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 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 > (1U << 16) ? (1U << 16) : dma_len;
}

static u32 fastlane_esp_dma_length_limit(struct esp *esp, u32 dma_addr,
                                        u32 dma_len)
{
        /* The old driver used 0xfffc as limit, so do that here too */
        return dma_len > 0xfffc ? 0xfffc : 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);
}

/* 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 blz1230_dma_registers __iomem *dregs = esp->dma_regs;
        u8 phase = esp->sreg & ESP_STAT_PMASK;

        /*
         * 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) {
                esp_send_pio_cmd(esp, (u32)esp->command_block, esp_count,
                                 dma_count, write, cmd);
                return;
        }

        /* Clear the results of a possible prior esp->ops->send_dma_cmd() */
        esp->send_cmd_error = 0;
        esp->send_cmd_residual = 0;

        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);

        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 blz1230II_dma_registers __iomem *dregs = esp->dma_regs;
        u8 phase = esp->sreg & ESP_STAT_PMASK;

        /* Use PIO if transferring message bytes to esp->command_block_dma */
        if (phase == ESP_MIP && addr == esp->command_block_dma) {
                esp_send_pio_cmd(esp, (u32)esp->command_block, esp_count,
                                 dma_count, write, cmd);
                return;
        }

        esp->send_cmd_error = 0;
        esp->send_cmd_residual = 0;

        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);

        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 blz2060_dma_registers __iomem *dregs = esp->dma_regs;
        u8 phase = esp->sreg & ESP_STAT_PMASK;

        /* Use PIO if transferring message bytes to esp->command_block_dma */
        if (phase == ESP_MIP && addr == esp->command_block_dma) {
                esp_send_pio_cmd(esp, (u32)esp->command_block, esp_count,
                                 dma_count, write, cmd);
                return;
        }

        esp->send_cmd_error = 0;
        esp->send_cmd_residual = 0;

        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);

        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;

        /* Use PIO if transferring message bytes to esp->command_block_dma */
        if (phase == ESP_MIP && addr == esp->command_block_dma) {
                esp_send_pio_cmd(esp, (u32)esp->command_block, esp_count,
                                 dma_count, write, cmd);
                return;
        }

        esp->send_cmd_error = 0;
        esp->send_cmd_residual = 0;

        zorro_esp_write8(esp, (esp_count >> 0) & 0xff, ESP_TCLOW);
        zorro_esp_write8(esp, (esp_count >> 8) & 0xff, ESP_TCMED);

        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 cyberII_dma_registers __iomem *dregs = esp->dma_regs;
        u8 phase = esp->sreg & ESP_STAT_PMASK;

        /* Use PIO if transferring message bytes to esp->command_block_dma */
        if (phase == ESP_MIP && addr == esp->command_block_dma) {
                esp_send_pio_cmd(esp, (u32)esp->command_block, esp_count,
                                 dma_count, write, cmd);
                return;
        }

        esp->send_cmd_error = 0;
        esp->send_cmd_residual = 0;

        zorro_esp_write8(esp, (esp_count >> 0) & 0xff, ESP_TCLOW);
        zorro_esp_write8(esp, (esp_count >> 8) & 0xff, ESP_TCMED);

        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;

        /* Use PIO if transferring message bytes to esp->command_block_dma */
        if (phase == ESP_MIP && addr == esp->command_block_dma) {
                esp_send_pio_cmd(esp, (u32)esp->command_block, esp_count,
                                 dma_count, write, cmd);
                return;
        }

        esp->send_cmd_error = 0;
        esp->send_cmd_residual = 0;

        zorro_esp_write8(esp, (esp_count >> 0) & 0xff, ESP_TCLOW);
        zorro_esp_write8(esp, (esp_count >> 8) & 0xff, ESP_TCMED);

        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)
{
        return esp->send_cmd_error;
}

/* per-board ESP driver ops */

static const struct esp_driver_ops blz1230_esp_ops = {
        .esp_write8             = zorro_esp_write8,
        .esp_read8              = zorro_esp_read8,
        .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,
        .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,
        .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,
        .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,
        .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,
        .irq_pending            = fastlane_esp_irq_pending,
        .dma_length_limit       = fastlane_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;
};

/* board types */

enum {
        ZORRO_BLZ1230,
        ZORRO_BLZ1230II,
        ZORRO_BLZ2060,
        ZORRO_CYBER,
        ZORRO_CYBERII,
        ZORRO_FASTLANE,
};

/* per-board config data */

static const struct zorro_driver_data zorro_esp_boards[] = {
        [ZORRO_BLZ1230] = {
                                .name           = "Blizzard 1230",
                                .offset         = 0x8000,
                                .dma_offset     = 0x10000,
                                .scsi_option    = 1,
                                .esp_ops        = &blz1230_esp_ops,
        },
        [ZORRO_BLZ1230II] = {
                                .name           = "Blizzard 1230II",
                                .offset         = 0x10000,
                                .dma_offset     = 0x10021,
                                .scsi_option    = 1,
                                .esp_ops        = &blz1230II_esp_ops,
        },
        [ZORRO_BLZ2060] = {
                                .name           = "Blizzard 2060",
                                .offset         = 0x1ff00,
                                .dma_offset     = 0x1ffe0,
                                .esp_ops        = &blz2060_esp_ops,
        },
        [ZORRO_CYBER] = {
                                .name           = "CyberStormI",
                                .offset         = 0xf400,
                                .dma_offset     = 0xf800,
                                .esp_ops        = &cyber_esp_ops,
        },
        [ZORRO_CYBERII] = {
                                .name           = "CyberStormII",
                                .offset         = 0x1ff03,
                                .dma_offset     = 0x1ff43,
                                .scsi_option    = 1,
                                .esp_ops        = &cyberII_esp_ops,
        },
        [ZORRO_FASTLANE] = {
                                .name           = "Fastlane",
                                .offset         = 0x1000001,
                                .dma_offset     = 0x1000041,
                                .esp_ops        = &fastlane_esp_ops,
        },
};

static const struct zorro_device_id zorro_esp_zorro_tbl[] = {
        {       /* Blizzard 1230 IV */
                .id = ZORRO_ID(PHASE5, 0x11, 0),
                .driver_data = ZORRO_BLZ1230,
        },
        {       /* Blizzard 1230 II (Zorro II) or Fastlane (Zorro III) */
                .id = ZORRO_ID(PHASE5, 0x0B, 0),
                .driver_data = ZORRO_BLZ1230II,
        },
        {       /* Blizzard 2060 */
                .id = ZORRO_ID(PHASE5, 0x18, 0),
                .driver_data = ZORRO_BLZ2060,
        },
        {       /* Cyberstorm */
                .id = ZORRO_ID(PHASE5, 0x0C, 0),
                .driver_data = ZORRO_CYBER,
        },
        {       /* Cyberstorm II */
                .id = ZORRO_ID(PHASE5, 0x19, 0),
                .driver_data = ZORRO_CYBERII,
        },
        { 0 }
};
MODULE_DEVICE_TABLE(zorro, zorro_esp_zorro_tbl);

static int zorro_esp_probe(struct zorro_dev *z,
                                       const struct zorro_device_id *ent)
{
        const 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 = &zorro_esp_boards[ent->driver_data];

        pr_info("%s found at address 0x%lx.\n", zdd->name, board);

        zep = kzalloc_obj(*zep);
        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->driver_data == ZORRO_BLZ1230II) {
                pr_info("%s at address 0x%lx is Fastlane Z3, fixing data!\n",
                        zdd->name, board);
                zdd = &zorro_esp_boards[ZORRO_FASTLANE];
        }

        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->driver_data == ZORRO_BLZ1230II) {
                /* map full address space up to ESP base for DMA */
                zep->board_base = ioremap(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(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;
        }

        esp->fifo_reg = esp->regs + ESP_FDATA * 4;

        /* 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(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);

        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);