public inbox for linux-m68k@lists.linux-m68k.org
 help / color / mirror / Atom feed
From: Michael Schmitz <schmitzmic@gmail.com>
To: geert@linux-m68k.org
Cc: linux-m68k@vger.kernel.org, Michael Schmitz <schmitz@debian.org>
Subject: [PATCH 2/2] m68k/amiga - Zorro ESP: convert old driver to ESP core
Date: Fri,  7 Jun 2013 08:56:39 +1200	[thread overview]
Message-ID: <1370552199-15048-3-git-send-email-schmitz@debian.org> (raw)
In-Reply-To: <1370552199-15048-1-git-send-email-schmitz@debian.org>

---
 drivers/scsi/zorro_esp.c |  414 ++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 414 insertions(+), 0 deletions(-)
 create mode 100644 drivers/scsi/zorro_esp.c

diff --git a/drivers/scsi/zorro_esp.c b/drivers/scsi/zorro_esp.c
new file mode 100644
index 0000000..b0d4a56
--- /dev/null
+++ b/drivers/scsi/zorro_esp.c
@@ -0,0 +1,414 @@
+/* zorrro_esp.c: ESP front-end for Amiga ZORRO SCSI systems.
+ *
+ * Copyright (C) 1996 Jesper Skov (jskov@cygnus.co.uk)
+ *
+ * Copyright (C) 2011 Michael Schmitz (schmitz@debian.org) for 
+ *               migration to ESP SCSI core
+ */
+/*
+ * 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>
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/dma-mapping.h>
+#include <linux/scatterlist.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 "esp_scsi.h"
+
+MODULE_AUTHOR("Michael Schmitz <schmitz@debian.org>");
+MODULE_DESCRIPTION("Amiga Zorro NCR5C9x (ESP) driver");
+MODULE_LICENSE("GPL");
+
+
+static struct scsi_host_template zorro_esp_scsi_driver_template = {
+	.proc_name	= "zorro-esp",
+	.this_id	= 7,
+	.module		= THIS_MODULE,
+};
+
+static struct zorro_driver_data {
+	const char *name;
+	unsigned long offset;
+	unsigned long dma_offset;
+	int absolute;
+	int zorro3;	/* offset is absolute address */
+} zorro_esp_driver_data[] = {
+	{ .name = "CyberStormI", .offset = 0xf400, .dma_offset = 0xf800 },
+	{ .name = "CyberStormII", .offset = 0x1ff03, .dma_offset = 0x1ff43 },
+	{ .name = "Blizzard 2060", .offset = 0x1ff00, .dma_offset = 0x1ffe0 },
+	{ .name = "Blizzard 1230", .offset = 0x8000, .dma_offset = 0x10000 },
+	{ .name = "Blizzard 1230II", .offset = 0x10000, .dma_offset = 0x10021 },
+	{ .name = "Fastlane", .offset = 0x1000001, .dma_offset = 0x1000041, .zorro3 = 1 },
+	{ 0 }
+};
+
+static struct zorro_device_id zorro_esp_zorro_tbl[] = {
+	{
+		.id = ZORRO_PROD_PHASE5_BLIZZARD_1220_CYBERSTORM,
+		.driver_data = (unsigned long)&zorro_esp_driver_data[0],
+	},
+	{
+		.id = ZORRO_PROD_PHASE5_BLIZZARD_1230_II_FASTLANE_Z3_CYBERSCSI_CYBERSTORM060,
+		.driver_data = (unsigned long)&zorro_esp_driver_data[0],
+	},
+	{
+		.id = ZORRO_PROD_PHASE5_CYBERSTORM_MK_II,
+		.driver_data = (unsigned long)&zorro_esp_driver_data[1],
+	},
+	{
+		.id = ZORRO_PROD_PHASE5_BLIZZARD_2060,
+		.driver_data = (unsigned long)&zorro_esp_driver_data[2],
+	},
+	{
+		.id = ZORRO_PROD_PHASE5_BLIZZARD_1230_IV_1260,
+		.driver_data = (unsigned long)&zorro_esp_driver_data[3],
+	},
+	{
+		.id = ZORRO_PROD_PHASE5_BLIZZARD_1230_II_FASTLANE_Z3_CYBERSCSI_CYBERSTORM060,
+		.driver_data = (unsigned long)&zorro_esp_driver_data[4],
+	},
+	{ 0 }
+};
+MODULE_DEVICE_TABLE(zorro, zorro_esp_zorro_tbl);
+
+/* The controller registers can be found in the Z2 config area at these
+ * offsets:
+ */
+#define BLZ2060_ESP_ADDR 0x1ff00
+#define BLZ2060_DMA_ADDR 0x1ffe0
+
+
+/* The Blizzard 2060 DMA interface
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ * Only two things can be programmed in the Blizzard DMA:
+ *  1) The data direction is controlled by the status of bit 31 (1 = write)
+ *  2) The source/dest address (word aligned, shifted one right) in bits 30-0
+ *
+ * Figure out interrupt status by reading the ESP status byte.
+ */
+struct blz2060_dma_registers {
+	volatile unsigned char dma_led_ctrl;	/* DMA led control   [0x000] */
+	unsigned char dmapad1[0x0f];
+	volatile unsigned char dma_addr0; 	/* DMA address (MSB) [0x010] */
+	unsigned char dmapad2[0x03];
+	volatile unsigned char dma_addr1; 	/* DMA address       [0x014] */
+	unsigned char dmapad3[0x03];
+	volatile unsigned char dma_addr2; 	/* DMA address       [0x018] */
+	unsigned char dmapad4[0x03];
+	volatile unsigned char dma_addr3; 	/* DMA address (LSB) [0x01c] */
+};
+
+#define BLZ2060_DMA_WRITE 0x80000000
+
+/* DMA control bits */
+#define BLZ2060_DMA_LED    0x02		/* HD led control 1 = off */
+
+
+/*
+ * m68k always assumes readl/writel operate on little endian
+ * mmio space; this is wrong at least for Sun3x, so we
+ * need to workaround this until a proper way is found
+ */
+#if 0
+#define dma_read32(REG) \
+	readl(esp->dma_regs + (REG))
+#define dma_write32(VAL, REG) \
+	writel((VAL), esp->dma_regs + (REG))
+#else
+#define dma_read32(REG) \
+	*(volatile u32 *)(esp->dma_regs + (REG))
+#define dma_write32(VAL, REG) \
+	do { *(volatile u32 *)(esp->dma_regs + (REG)) = (VAL); } while (0)
+#endif
+
+/*
+ * 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 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 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 zorro_esp_send_dma_cmd(struct esp *esp, u32 addr, u32 esp_count,
+				  u32 dma_count, int write, u8 cmd)
+{
+	struct blz2060_dma_registers *dregs = 
+		(struct blz2060_dma_registers *) (esp->dma_regs);
+
+	BUG_ON(!(cmd & ESP_CMD_DMA));
+	zorro_esp_write8(esp, (esp_count >> 0) & 0xff, ESP_TCLOW);
+	zorro_esp_write8(esp, (esp_count >> 8) & 0xff, ESP_TCMED);
+
+	/* 
+	 * This will differ among Amiga ESP implementations - DMA setup!
+	 */
+
+	if (write)
+		cache_clear(addr, esp_count);
+	else
+		cache_push(addr, esp_count);
+
+	/* On the Sparc, DMA_ST_WRITE means "move data from device to memory"
+	 * so when (write) is true, it actually means READ (from the ESP)!
+	 */
+	addr >>= 1;
+	if (write)
+		addr &= ~(BLZ2060_DMA_WRITE);
+	else
+		addr |= BLZ2060_DMA_WRITE;
+
+	dregs->dma_addr3 = (addr      ) & 0xff;
+	dregs->dma_addr2 = (addr >>  8) & 0xff;
+	dregs->dma_addr1 = (addr >> 16) & 0xff;
+	dregs->dma_addr0 = (addr >> 24) & 0xff;
+
+	scsi_esp_cmd(esp, cmd);
+}
+
+static int zorro_esp_dma_error(struct esp *esp)
+{
+	/* nothing to do here - there seems to be no way to check for DMA errors */
+	return 0;
+}
+
+static const struct esp_driver_ops zorro_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,
+	.reset_dma	=	zorro_esp_reset_dma,
+	.dma_drain	=	zorro_esp_dma_drain,
+	.dma_invalidate	=	zorro_esp_dma_invalidate,
+	.send_dma_cmd	=	zorro_esp_send_dma_cmd,
+	.dma_error	=	zorro_esp_dma_error,
+};
+
+static int zorro_esp_init_one(struct zorro_dev *z,
+				       const struct zorro_device_id *ent)
+{
+	struct scsi_host_template *tpnt = &zorro_esp_scsi_driver_template;
+	struct Scsi_Host *host;
+	struct esp *esp;
+	struct zorro_driver_data *zdd;
+	unsigned long board, ioaddr, dmaaddr, esp_base;
+	int err = -ENOMEM;
+
+	board = zorro_resource_start(z);
+	zdd = (struct zorro_driver_data *)ent->driver_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)) {
+		printk(KERN_ERR "zorro_esp: cannot reserve region 0x%lx, abort\n",
+		       board);
+		return -EBUSY;
+	}
+
+	/* Fill in the required pieces of hostdata */
+	if (ioaddr > 0x01000000)
+		esp_base = ioremap(ioaddr, zorro_resource_len(z));
+	else
+		esp_base = (void __iomem *)ZTWO_VADDR(ioaddr);
+
+	zorro_esp_scsi_driver_template.name = zdd->name;
+
+	/* and register the chip */
+	host = scsi_host_alloc(tpnt, sizeof(struct esp));
+
+	if (!host) {
+		printk(KERN_ERR "zorro_esp: No host detected; "
+				"board configuration problem?\n");
+		goto out_free;
+	}
+
+	host->max_id = 8;
+	esp = shost_priv(host);
+
+	esp->host = host;
+	esp->dev = z;
+	esp->ops = &zorro_esp_ops;
+
+	esp->regs = ioremap_nocache(ioaddr, 0x20);
+	if (!esp->regs)
+		goto fail_unmap_regs;
+
+	esp->dma_regs = ioremap_nocache(dmaaddr, 0x20);
+
+	esp->command_block = dma_alloc_coherent(esp->dev, 32,
+						&esp->command_block_dma,
+						GFP_KERNEL);
+	if (!esp->command_block)
+		goto fail_unmap_regs_dma;
+
+	host->irq = IRQ_AMIGA_PORTS;
+	err = request_irq(host->irq, scsi_esp_intr, IRQF_SHARED,
+			  "Amiga Zorro ESP", esp);
+	if (err < 0)
+		goto fail_unmap_command_block;
+
+	esp->scsi_id = 7;
+	esp->host->this_id = esp->scsi_id;
+	esp->scsi_id_mask = (1 << esp->scsi_id);
+	esp->cfreq = 20000000;
+
+	dev_set_drvdata(&z->dev, esp);
+
+	err = scsi_esp_register(esp, &z->dev);
+	if (err)
+		goto fail_free_irq;
+
+	zorro_set_drvdata(z, host);
+	scsi_scan_host(host);
+
+	return 0;
+
+fail_free_irq:
+	free_irq(host->irq, esp);
+fail_unmap_command_block:
+	dma_free_coherent(esp->dev, 16,
+			  esp->command_block,
+			  esp->command_block_dma);
+fail_unmap_regs_dma:
+	iounmap(esp->dma_regs);
+fail_unmap_regs:
+	iounmap(esp->regs);
+	scsi_host_put(host);
+out_free:
+	if (ioaddr > 0x01000000)
+		iounmap(esp_base);
+out_release:
+	zorro_release_device(z);
+
+	return -ENODEV;
+}
+
+static void zorro_esp_remove_one(struct zorro_dev *z)
+{
+	struct Scsi_Host *host = zorro_get_drvdata(z);
+	struct esp *esp = dev_get_drvdata(&z->dev);
+	unsigned int irq = esp->host->irq;
+	u32 val;
+
+	scsi_esp_unregister(esp);
+
+	/* Disable interrupts. Perhaps use disable_irq instead ... */
+
+	free_irq(irq, esp);
+	dma_free_coherent(esp->dev, 16,
+			  esp->command_block,
+			  esp->command_block_dma);
+
+	scsi_host_put(esp->host);
+
+	zorro_release_device(z);
+}
+
+static struct zorro_driver zorro_esp_driver = {
+	.name	  = "zorro_esp-scsi",
+	.id_table = zorro_esp_zorro_tbl,
+	.probe	  = zorro_esp_init_one,
+	.remove	  = zorro_esp_remove_one,
+};
+
+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);
-- 
1.7.0.4

  parent reply	other threads:[~2013-06-06 20:57 UTC|newest]

Thread overview: 53+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-06-06 20:56 [PATCH 0/2] Experimental Amiga Zorro ESP driver Michael Schmitz
2013-06-06 20:56 ` [PATCH 1/2] m68k/amiga - Zorro ESP SCSI Makefile/Kconfig support Michael Schmitz
2013-06-06 20:56 ` Michael Schmitz [this message]
2013-08-15 21:40 ` [PATCH 0/2] Experimental Amiga Zorro ESP driver Tuomas Vainikka
2013-08-16 19:01   ` Tuomas Vainikka
2013-08-17  1:49     ` Michael Schmitz
2013-08-17 11:33       ` Tuomas Vainikka
2013-08-18  2:05         ` Michael Schmitz
2013-08-18  8:23           ` Geert Uytterhoeven
2013-08-18  8:58             ` Michael Schmitz
2013-08-18  9:10               ` Geert Uytterhoeven
2013-08-19  8:48                 ` Michael Schmitz
2013-08-19 11:47                   ` Tuomas Vainikka
2013-08-19 12:01                     ` Geert Uytterhoeven
2013-08-19 20:46                   ` Tuomas Vainikka
2013-08-20  9:36                     ` Michael Schmitz
2013-08-20 10:00                       ` Tuomas Vainikka
2013-08-22 20:34                         ` Michael Schmitz
2013-08-31 10:37                           ` Tuomas Vainikka
2013-09-10 21:13                           ` Tuomas Vainikka
2013-09-11 10:12                             ` Michael Schmitz
2013-09-11 13:08                               ` Tuomas Vainikka
2013-09-11 20:14                                 ` Tuomas Vainikka
2013-09-26 13:44                                 ` Michael Schmitz
2013-09-26 14:04                                   ` Tuomas Vainikka
2013-09-27  9:17                                     ` Michael Schmitz
2013-09-11 14:48                               ` Geert Uytterhoeven
2013-09-12 15:36                                 ` esp_scsi QTAG in FAS216 (was Re: [PATCH 0/2] Experimental Amiga Zorro ESP driver) Tuomas Vainikka
2013-09-26 13:50                                   ` Michael Schmitz
2014-04-04 20:28                                   ` esp_scsi QTAG in FAS216 David Miller
2014-04-06 20:33                                     ` Michael Schmitz
2014-04-07  3:39                                       ` David Miller
2014-04-10 14:31                                       ` Kars de Jong
2014-04-11  1:47                                         ` Michael Schmitz
2014-04-13 14:47                                           ` Kars de Jong
2014-04-13 22:38                                             ` Michael Schmitz
2014-04-14  2:14                                               ` David Miller
2014-04-14  5:05                                                 ` Tuomas Vainikka
2014-04-14  8:51                                                   ` Michael Schmitz
2014-05-25  8:56                                                     ` Geert Uytterhoeven
2014-05-26  1:15                                                       ` Michael Schmitz
2014-04-14  9:01                                                 ` Michael Schmitz
2014-05-04 11:41                                                   ` Tuomas Vainikka
2016-10-28 21:54                                                 ` Finn Thain
2016-10-30  2:33                                                   ` Finn Thain
2016-10-31  8:03                                                     ` Michael Schmitz
2016-10-31 18:54                                                       ` Michael Schmitz
2016-10-31 23:47                                                         ` Finn Thain
2016-11-01  7:09                                                           ` Michael Schmitz
2016-11-01  7:23                                                             ` Finn Thain
2013-08-18  9:14               ` [PATCH 0/2] Experimental Amiga Zorro ESP driver Tuomas Vainikka
2013-08-18  9:42                 ` Geert Uytterhoeven
2013-08-18 12:25                   ` Tuomas Vainikka

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1370552199-15048-3-git-send-email-schmitz@debian.org \
    --to=schmitzmic@gmail.com \
    --cc=geert@linux-m68k.org \
    --cc=linux-m68k@vger.kernel.org \
    --cc=schmitz@debian.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox